source: wokkel/test/test_muc.py @ 112:be0b126081f2

wokkel-muc-client-support-24
Last change on this file since 112:be0b126081f2 was 112:be0b126081f2, checked in by Christopher Zorn <tofu@…>, 13 years ago

all tests pass, needs comments, also need to get the entire xep in the tests

File size: 10.7 KB
Line 
1# Copyright (c) 2003-2008 Ralph Meijer
2# See LICENSE for details.
3
4"""
5Tests for L{wokkel.muc}
6"""
7
8from zope.interface import verify
9
10from twisted.trial import unittest
11from twisted.internet import defer
12from twisted.words.xish import domish, xpath
13from twisted.words.protocols.jabber import error
14from twisted.words.protocols.jabber.jid import JID
15
16from wokkel import data_form, iwokkel, muc, shim, disco
17from wokkel.generic import parseXml
18from wokkel.test.helpers import XmlStreamStub
19
20try:
21    from twisted.words.protocols.jabber.xmlstream import toResponse
22except ImportError:
23    from wokkel.compat import toResponse
24
25
26def calledAsync(fn):
27    """
28    Function wrapper that fires a deferred upon calling the given function.
29    """
30    d = defer.Deferred()
31
32    def func(*args, **kwargs):
33        try:
34            result = fn(*args, **kwargs)
35        except:
36            d.errback()
37        else:
38            d.callback(result)
39
40    return d, func
41
42
43class MucClientTest(unittest.TestCase):
44    timeout = 2
45
46    def setUp(self):
47        self.stub = XmlStreamStub()
48        self.protocol = muc.MUCClient()
49        self.protocol.xmlstream = self.stub.xmlstream
50        self.protocol.connectionInitialized()
51        self.test_room = 'test'
52        self.test_srv  = 'conference.example.org'
53        self.test_nick = 'Nick'
54
55        self.room_jid = JID(self.test_room+'@'+self.test_srv+'/'+self.test_nick)
56
57        self.user_jid = JID('test@jabber.org/Testing')
58
59    def test_interface(self):
60        """
61        Do instances of L{muc.MUCClient} provide L{iwokkel.IMUCClient}?
62        """
63        verify.verifyObject(iwokkel.IMUCClient, self.protocol)
64
65
66    def test_presence(self):
67        """Test receiving room presence
68        """
69        p = muc.UserPresence()
70       
71        def userPresence(prs):
72            self.failUnless(len(prs.children)==1, 'Not enough children')
73            self.failUnless(getattr(prs,'x',None), 'No x element')
74                   
75       
76        d, self.protocol.receivedUserPresence = calledAsync(userPresence)
77        self.stub.send(p)
78        return d
79
80
81    def test_groupChat(self):
82        """Test receiving room presence
83        """
84        m = muc.GroupChat('test@test.com',body='test')
85       
86        def groupChat(elem):
87            self.failUnless(elem.name=='message','Wrong stanza')
88            self.failUnless(elem['type'] == 'groupchat', 'Wrong attribute')
89                           
90       
91        d, self.protocol.receivedGroupChat = calledAsync(groupChat)
92        self.stub.send(m)
93        return d
94
95
96    def test_discoServerSupport(self):
97        """Test for disco support from a server.
98        """
99        test_srv = 'shakespeare.lit'
100
101        def cb(query):
102            # check namespace
103            self.failUnless(query.uri==disco.NS_INFO, 'Wrong namespace')
104           
105
106        d = self.protocol.disco(test_srv)
107        d.addCallback(cb)
108
109        iq = self.stub.output[-1]
110       
111        # send back a response
112        response = toResponse(iq, 'result')
113        response.addElement('query', disco.NS_INFO)
114        # need to add information to response
115        response.query.addChild(disco.DiscoFeature(muc.NS))
116        response.query.addChild(disco.DiscoIdentity(category='conference',
117                                                    name='Macbeth Chat Service',
118                                                    type='text'))
119       
120        self.stub.send(response)
121        return d
122       
123
124       
125    def test_joinRoom(self):
126        """Test joining a room
127        """
128       
129
130        def cb(room):
131            self.assertEquals(self.test_room, room.name)
132
133        d = self.protocol.join(self.test_srv, self.test_room, self.test_nick)
134        d.addCallback(cb)
135
136        prs = self.stub.output[-1]
137        self.failUnless(prs.name=='presence', "Need to be presence")
138        self.failUnless(getattr(prs, 'x', None), 'No muc x element')
139
140        # send back user presence, they joined       
141        response = muc.UserPresence(frm=self.test_room+'@'+self.test_srv+'/'+self.test_nick)
142        self.stub.send(response)
143        return d
144
145
146    def test_joinRoomForbidden(self):
147        """Test joining a room and getting an error
148        """
149
150        def cb(error):
151            self.failUnless(isinstance(error.value,muc.PresenceError), 'Wrong type')
152            self.failUnless(error.value['type']=='error', 'Not an error returned')
153           
154           
155        d = self.protocol.join(self.test_srv, self.test_room, self.test_nick)
156        d.addBoth(cb)
157
158        prs = self.stub.output[-1]
159        self.failUnless(prs.name=='presence', "Need to be presence")
160        self.failUnless(getattr(prs, 'x', None), 'No muc x element')
161        # send back user presence, they joined
162       
163        response = muc.PresenceError(error=muc.MUCError('auth',
164                                                        'forbidden'
165                                                        ),
166                                     frm=self.room_jid.full())
167        self.stub.send(response)
168        return d       
169
170    def test_partRoom(self):
171       
172        def cb(left):
173            self.failUnless(left, 'did not leave room')
174
175
176        d = self.protocol.leave(self.room_jid)
177        d.addCallback(cb)
178
179        prs = self.stub.output[-1]
180       
181        self.failUnless(prs['type']=='unavailable', 'Unavailable is not being sent')
182       
183        response = prs
184        response['from'] = response['to']
185        response['to'] = 'test@jabber.org'
186
187        self.stub.send(response)
188        return d
189       
190
191    def test_ban(self):
192       
193        banned = JID('ban@jabber.org/TroubleMakger')
194        def cb(banned):
195            self.failUnless(banned, 'Did not ban user')
196
197           
198        d = self.protocol.ban(self.room_jid, banned, self.user_jid, reason='Spam')
199        d.addCallback(cb)
200
201        iq = self.stub.output[-1]
202       
203        self.failUnless(xpath.matches("/iq[@type='set' and @to='%s']/query/item[@affiliation='outcast']" % (self.room_jid.userhost(),), iq), 'Wrong ban stanza')
204
205        response = toResponse(iq, 'result')
206
207        self.stub.send(response)
208
209        return d
210
211
212    def test_kick(self):
213
214        kicked = JID('kick@jabber.org/TroubleMakger')
215        def cb(kicked):
216            self.failUnless(kicked, 'Did not kick user')
217
218           
219        d = self.protocol.kick(self.room_jid, kicked, self.user_jid, reason='Spam')
220        d.addCallback(cb)
221
222        iq = self.stub.output[-1]
223       
224        self.failUnless(xpath.matches("/iq[@type='set' and @to='%s']/query/item[@affiliation='none']" % (self.room_jid.userhost(),), iq), 'Wrong kick stanza')
225
226        response = toResponse(iq, 'result')
227
228        self.stub.send(response)
229
230        return d
231
232        self.fail('Not Implemented')
233       
234
235    def test_password(self):
236        """Test sending a password via presence to a password protected room.
237        """
238       
239        self.protocol.password(self.room_jid, 'secret')
240       
241        prs = self.stub.output[-1]
242       
243        self.failUnless(xpath.matches("/presence[@to='%s']/x/password[text()='secret']" % (self.room_jid.full(),), prs), 'Wrong presence stanza')
244
245
246    def test_history(self):
247        """Test receiving history on room join.
248        """
249        m = muc.HistoryMessage(self.room_jid.userhost(), self.protocol._makeTimeStamp(), body='test')
250       
251        def roomHistory(h):
252            self.failUnless(getattr(h,'delay',None), 'No delay element')
253                   
254
255        d, self.protocol.receivedHistory = calledAsync(roomHistory)
256        self.stub.send(m)
257        return d
258
259
260    def test_oneToOneChat(self):
261        """Test converting a one to one chat
262        """
263        archive = []
264        thread = "e0ffe42b28561960c6b12b944a092794b9683a38"
265        # create messages
266        msg = domish.Element((None, 'message'))
267        msg['to'] = 'testing@example.com'
268        msg['type'] = 'chat'
269        msg.addElement('body', None, 'test')
270        msg.addElement('thread', None, thread)
271
272        archive.append(msg)
273
274        msg = domish.Element((None, 'message'))
275        msg['to'] = 'testing2@example.com'
276        msg['type'] = 'chat'
277        msg.addElement('body', None, 'yo')
278        msg.addElement('thread', None, thread)
279
280        archive.append(msg)
281
282        self.protocol.history(self.room_jid.userhost(), archive)
283
284
285        while len(self.stub.output)>0:
286            m = self.stub.output.pop()
287            # check for delay element
288            self.failUnless(m.name=='message', 'Wrong stanza')
289            self.failUnless(xpath.matches("/message/delay", m), 'Invalid history stanza')
290       
291
292    def test_invite(self):
293        other_jid = 'test@jabber.org'
294
295        self.protocol.invite(other_jid, 'This is a test')
296
297        msg = self.stub.output[-1]
298
299        self.failUnless(xpath.matches("/message[@to='%s']/x/invite/reason" % (other_jid,), msg), 'Wrong message type')
300
301
302       
303    def test_privateMessage(self):
304        """Test sending private messages to muc entities.
305        """
306        other_nick = self.room_jid.userhost()+'/OtherNick'
307
308        self.protocol.chat(other_nick, 'This is a test')
309
310        msg = self.stub.output[-1]
311
312        self.failUnless(xpath.matches("/message[@type='chat' and @to='%s']/body" % (other_nick,), msg), 'Wrong message type')
313
314
315    def test_register(self):
316        """Test client registering with a room. http://xmpp.org/extensions/xep-0045.html#register
317
318        """
319       
320        def cb(iq):
321            # check for a result
322            self.failUnless(iq['type']=='result', 'We did not get a result')
323       
324        d = self.protocol.register(self.room_jid.userhost())
325        d.addCallback(cb)
326
327        iq = self.stub.output[-1]
328       
329        self.failUnless(xpath.matches("/iq/query[@xmlns='%s']" % (muc.NS_REQUEST), iq), 'Invalid iq register request')
330       
331        response = toResponse(iq, 'result')
332        self.stub.send(response)
333        return d
334
335    def test_voice(self):
336        """
337        """
338        self.protocol.voice(self.room_jid.userhost())
339
340        m = self.stub.output[-1]
341       
342        self.failUnless(xpath.matches("/message/x[@type='submit']/field/value[text()='%s']" % (muc.NS_REQUEST,), m), 'Invalid voice message stanza')
343
344
345    def test_roomConfigure(self):
346        """
347        """
348
349        def cb(iq):
350            self.failUnless(iq['type']=='result', 'Not a result')
351           
352
353        fields = []
354
355        fields.append(data_form.Field(label='Natural-Language Room Name',
356                                      var='muc#roomconfig_roomname',
357                                      value=self.test_room))
358       
359        d = self.protocol.configure(self.room_jid.userhost(), fields)
360        d.addCallback(cb)
361
362        iq = self.stub.output[-1]
363        self.failUnless(xpath.matches("/iq/query[@xmlns='%s']/x"% (muc.NS_OWNER,), iq), 'Bad configure request')
364       
365        response = toResponse(iq, 'result')
366        self.stub.send(response)
367        return d
368
369
Note: See TracBrowser for help on using the repository browser.