~certify-web-dev/twisted/certify-trunk

« back to all changes in this revision

Viewing changes to twisted/words/test/test_service.py

  • Committer: Bazaar Package Importer
  • Author(s): Matthias Klose
  • Date: 2007-01-17 14:52:35 UTC
  • mfrom: (1.1.5 upstream) (2.1.2 etch)
  • Revision ID: james.westby@ubuntu.com-20070117145235-btmig6qfmqfen0om
Tags: 2.5.0-0ubuntu1
New upstream version, compatible with python2.5.

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
# Copyright (c) 2001-2005 Twisted Matrix Laboratories.
 
2
# See LICENSE for details.
 
3
 
 
4
from __future__ import generators
 
5
 
 
6
import time
 
7
 
 
8
from zope.interface import implements
 
9
 
 
10
from twisted.trial import unittest
 
11
from twisted.test import proto_helpers
 
12
 
 
13
from twisted.cred import portal, credentials, checkers
 
14
from twisted.words import ewords, iwords, service
 
15
from twisted.words.protocols import irc
 
16
from twisted.spread import pb
 
17
from twisted.internet.defer import Deferred, DeferredList, maybeDeferred, succeed
 
18
from twisted.internet.defer import deferredGenerator as dG, waitForDeferred as wFD
 
19
from twisted.internet import address, reactor
 
20
 
 
21
class RealmTestCase(unittest.TestCase):
 
22
    def _entityCreationTest(self, kind):
 
23
        # Kind is "user" or "group"
 
24
        realm = service.InMemoryWordsRealm("realmname")
 
25
 
 
26
        name = u'test' + kind.lower()
 
27
        create = getattr(realm, 'create' + kind.title())
 
28
        get = getattr(realm, 'get' + kind.title())
 
29
        flag = 'create' + kind.title() + 'OnRequest'
 
30
        dupExc = getattr(ewords, 'Duplicate' + kind.title())
 
31
        noSuchExc = getattr(ewords, 'NoSuch' + kind.title())
 
32
 
 
33
        # Creating should succeed
 
34
        d = wFD(create(name))
 
35
        yield d
 
36
        p = d.getResult()
 
37
        self.assertEquals(p.name, name)
 
38
 
 
39
        # Creating the same user again should not
 
40
        d = wFD(create(name))
 
41
        yield d
 
42
        self.assertRaises(dupExc, d.getResult)
 
43
 
 
44
        # Getting a non-existent user should succeed if createUserOnRequest is True
 
45
        setattr(realm, flag, True)
 
46
        d = wFD(get(u"new" + kind.lower()))
 
47
        yield d
 
48
        p = d.getResult()
 
49
        self.assertEquals(p.name, "new" + kind.lower())
 
50
 
 
51
        # Getting that user again should return the same object
 
52
        d = wFD(get(u"new" + kind.lower()))
 
53
        yield d
 
54
        newp = d.getResult()
 
55
        self.assertIdentical(p, newp)
 
56
 
 
57
        # Getting a non-existent user should fail if createUserOnRequest is False
 
58
        setattr(realm, flag, False)
 
59
        d = wFD(get(u"another" + kind.lower()))
 
60
        yield d
 
61
        self.assertRaises(noSuchExc, d.getResult)
 
62
    _entityCreationTest = dG(_entityCreationTest)
 
63
 
 
64
 
 
65
    def testUserCreation(self):
 
66
        return self._entityCreationTest("User")
 
67
 
 
68
 
 
69
    def testGroupCreation(self):
 
70
        return self._entityCreationTest("Group")
 
71
 
 
72
 
 
73
    def testUserRetrieval(self):
 
74
        realm = service.InMemoryWordsRealm("realmname")
 
75
 
 
76
        # Make a user to play around with
 
77
        d = wFD(realm.createUser(u"testuser"))
 
78
        yield d
 
79
        user = d.getResult()
 
80
 
 
81
        # Make sure getting the user returns the same object
 
82
        d = wFD(realm.getUser(u"testuser"))
 
83
        yield d
 
84
        retrieved = d.getResult()
 
85
        self.assertIdentical(user, retrieved)
 
86
 
 
87
        # Make sure looking up the user also returns the same object
 
88
        d = wFD(realm.lookupUser(u"testuser"))
 
89
        yield d
 
90
        lookedUp = d.getResult()
 
91
        self.assertIdentical(retrieved, lookedUp)
 
92
 
 
93
        # Make sure looking up a user who does not exist fails
 
94
        d = wFD(realm.lookupUser(u"nosuchuser"))
 
95
        yield d
 
96
        self.assertRaises(ewords.NoSuchUser, d.getResult)
 
97
    testUserRetrieval = dG(testUserRetrieval)
 
98
 
 
99
 
 
100
    def testUserAddition(self):
 
101
        realm = service.InMemoryWordsRealm("realmname")
 
102
 
 
103
        # Create and manually add a user to the realm
 
104
        p = service.User("testuser")
 
105
        d = wFD(realm.addUser(p))
 
106
        yield d
 
107
        user = d.getResult()
 
108
        self.assertIdentical(p, user)
 
109
 
 
110
        # Make sure getting that user returns the same object
 
111
        d = wFD(realm.getUser(u"testuser"))
 
112
        yield d
 
113
        retrieved = d.getResult()
 
114
        self.assertIdentical(user, retrieved)
 
115
 
 
116
        # Make sure looking up that user returns the same object
 
117
        d = wFD(realm.lookupUser(u"testuser"))
 
118
        yield d
 
119
        lookedUp = d.getResult()
 
120
        self.assertIdentical(retrieved, lookedUp)
 
121
    testUserAddition = dG(testUserAddition)
 
122
 
 
123
 
 
124
    def testGroupRetrieval(self):
 
125
        realm = service.InMemoryWordsRealm("realmname")
 
126
 
 
127
        d = wFD(realm.createGroup(u"testgroup"))
 
128
        yield d
 
129
        group = d.getResult()
 
130
 
 
131
        d = wFD(realm.getGroup(u"testgroup"))
 
132
        yield d
 
133
        retrieved = d.getResult()
 
134
 
 
135
        self.assertIdentical(group, retrieved)
 
136
 
 
137
        d = wFD(realm.getGroup(u"nosuchgroup"))
 
138
        yield d
 
139
        self.assertRaises(ewords.NoSuchGroup, d.getResult)
 
140
    testGroupRetrieval = dG(testGroupRetrieval)
 
141
 
 
142
 
 
143
    def testGroupAddition(self):
 
144
        realm = service.InMemoryWordsRealm("realmname")
 
145
 
 
146
        p = service.Group("testgroup")
 
147
        d = wFD(realm.addGroup(p))
 
148
        yield d
 
149
        d.getResult()
 
150
 
 
151
        d = wFD(realm.getGroup(u"testGroup"))
 
152
        yield d
 
153
        group = d.getResult()
 
154
 
 
155
        self.assertIdentical(p, group)
 
156
    testGroupAddition = dG(testGroupAddition)
 
157
 
 
158
    
 
159
    def testGroupUsernameCollision(self):
 
160
        """
 
161
        Try creating a group with the same name as an existing user and
 
162
        assert that it succeeds, since users and groups should not be in the
 
163
        same namespace and collisions should be impossible.
 
164
        """
 
165
        realm = service.InMemoryWordsRealm("realmname")
 
166
 
 
167
        d = wFD(realm.createUser(u"test"))
 
168
        yield d
 
169
        user = d.getResult()
 
170
 
 
171
        d = wFD(realm.createGroup(u"test"))
 
172
        yield d
 
173
        group = d.getResult()
 
174
    testGroupUsernameCollision = dG(testGroupUsernameCollision)
 
175
 
 
176
 
 
177
    def testEnumeration(self):
 
178
        realm = service.InMemoryWordsRealm("realmname")
 
179
        d = wFD(realm.createGroup(u"groupone"))
 
180
        yield d
 
181
        d.getResult()
 
182
 
 
183
        d = wFD(realm.createGroup(u"grouptwo"))
 
184
        yield d
 
185
        d.getResult()
 
186
 
 
187
        groups = wFD(realm.itergroups())
 
188
        yield groups
 
189
        groups = groups.getResult()
 
190
 
 
191
        n = [g.name for g in groups]
 
192
        n.sort()
 
193
        self.assertEquals(n, ["groupone", "grouptwo"])
 
194
    testEnumeration = dG(testEnumeration)
 
195
 
 
196
 
 
197
class TestGroup(object):
 
198
    def __init__(self, name, size, topic):
 
199
        self.name = name
 
200
        self.size = lambda: size
 
201
        self.meta = {'topic': topic}
 
202
 
 
203
 
 
204
class TestUser(object):
 
205
    def __init__(self, name, groups, signOn, lastMessage):
 
206
        self.name = name
 
207
        self.itergroups = lambda: iter([TestGroup(g, 3, 'Hello') for g in groups])
 
208
        self.signOn = signOn
 
209
        self.lastMessage = lastMessage
 
210
 
 
211
 
 
212
class TestPortal(object):
 
213
    def __init__(self):
 
214
        self.logins = []
 
215
 
 
216
    def login(self, credentials, mind, *interfaces):
 
217
        d = Deferred()
 
218
        self.logins.append((credentials, mind, interfaces, d))
 
219
        return d
 
220
 
 
221
 
 
222
class TestCaseUserAgg(object):
 
223
    def __init__(self, user, realm, factory, address=address.IPv4Address('TCP', '127.0.0.1', 54321)):
 
224
        self.user = user
 
225
        self.transport = proto_helpers.StringTransportWithDisconnection()
 
226
        self.protocol = factory.buildProtocol(address)
 
227
        self.transport.protocol = self.protocol
 
228
        self.user.mind = self.protocol
 
229
        self.protocol.makeConnection(self.transport)
 
230
 
 
231
    def write(self, stuff):
 
232
        if isinstance(stuff, unicode):
 
233
            stuff = stuff.encode('utf-8')
 
234
        self.protocol.dataReceived(stuff)
 
235
 
 
236
 
 
237
class IRCProtocolTestCase(unittest.TestCase):
 
238
    STATIC_USERS = [
 
239
        u'useruser', u'otheruser', u'someguy', u'firstuser', u'username',
 
240
        u'userone', u'usertwo', u'userthree', u'someuser']
 
241
 
 
242
    def setUp(self):
 
243
        self.realm = service.InMemoryWordsRealm("realmname")
 
244
        self.checker = checkers.InMemoryUsernamePasswordDatabaseDontUse()
 
245
        self.portal = portal.Portal(self.realm, [self.checker])
 
246
        self.factory = service.IRCFactory(self.realm, self.portal)
 
247
 
 
248
        c = []
 
249
        for nick in self.STATIC_USERS:
 
250
            c.append(self.realm.createUser(nick))
 
251
            self.checker.addUser(nick.encode('ascii'), nick + "_password")
 
252
        return DeferredList(c)
 
253
 
 
254
 
 
255
    def _assertGreeting(self, user):
 
256
        # Make sure we get 1-4 at least
 
257
        response = self._response(user)
 
258
        expected = range(1, 5)
 
259
        for (prefix, command, args) in response:
 
260
            try:
 
261
                expected.remove(int(command))
 
262
            except KeyError:
 
263
                pass
 
264
        self.failIf(expected, "Missing responses for %r" % (expected,))
 
265
 
 
266
 
 
267
    def _login(self, user, nick, password=None):
 
268
        if password is None:
 
269
            password = nick + "_password"
 
270
        user.write('PASS %s\r\n' % (password,))
 
271
        user.write('NICK %s extrainfo\r\n' % (nick,))
 
272
 
 
273
 
 
274
    def _loggedInUser(self, name):
 
275
        d = wFD(self.realm.lookupUser(name))
 
276
        yield d
 
277
        user = d.getResult()
 
278
        agg = TestCaseUserAgg(user, self.realm, self.factory)
 
279
        self._login(agg, name)
 
280
        yield agg
 
281
    _loggedInUser = dG(_loggedInUser)
 
282
 
 
283
 
 
284
    def _response(self, user):
 
285
        response = user.transport.value().splitlines()
 
286
        user.transport.clear()
 
287
        return map(irc.parsemsg, response)
 
288
 
 
289
 
 
290
    def testPASSLogin(self):
 
291
        user = wFD(self._loggedInUser(u'firstuser'))
 
292
        yield user
 
293
        user = user.getResult()
 
294
        self._assertGreeting(user)
 
295
    testPASSLogin = dG(testPASSLogin)
 
296
 
 
297
 
 
298
    def testNickServLogin(self):
 
299
        firstuser = wFD(self.realm.lookupUser(u'firstuser'))
 
300
        yield firstuser
 
301
        firstuser = firstuser.getResult()
 
302
 
 
303
        user = TestCaseUserAgg(firstuser, self.realm, self.factory)
 
304
        user.write('NICK firstuser extrainfo\r\n')
 
305
        response = self._response(user)
 
306
        self.assertEquals(len(response), 1)
 
307
        self.assertEquals(response[0][0], service.NICKSERV)
 
308
        self.assertEquals(response[0][1], 'PRIVMSG')
 
309
        self.assertEquals(response[0][2], ['firstuser', 'Password?'])
 
310
        user.transport.clear()
 
311
 
 
312
        user.write('PRIVMSG nickserv firstuser_password\r\n')
 
313
        self._assertGreeting(user)
 
314
    testNickServLogin = dG(testNickServLogin)
 
315
 
 
316
 
 
317
    def testFailedLogin(self):
 
318
        firstuser = wFD(self.realm.lookupUser(u'firstuser'))
 
319
        yield firstuser
 
320
        firstuser = firstuser.getResult()
 
321
 
 
322
        user = TestCaseUserAgg(firstuser, self.realm, self.factory)
 
323
        self._login(user, "firstuser", "wrongpass")
 
324
        response = self._response(user)
 
325
        self.assertEquals(len(response), 1)
 
326
        self.assertEquals(response[0][2], ['firstuser', 'Login failed.  Goodbye.'])
 
327
    testFailedLogin = dG(testFailedLogin)
 
328
 
 
329
 
 
330
    def testLogout(self):
 
331
        logout = []
 
332
        firstuser = wFD(self.realm.lookupUser(u'firstuser'))
 
333
        yield firstuser
 
334
        firstuser = firstuser.getResult()
 
335
 
 
336
        user = TestCaseUserAgg(firstuser, self.realm, self.factory)
 
337
        self._login(user, "firstuser")
 
338
        user.protocol.logout = lambda: logout.append(True)
 
339
        user.write('QUIT\r\n')
 
340
        self.assertEquals(logout, [True])
 
341
    testLogout = dG(testLogout)
 
342
 
 
343
 
 
344
    def testJoin(self):
 
345
        firstuser = wFD(self.realm.lookupUser(u'firstuser'))
 
346
        yield firstuser
 
347
        firstuser = firstuser.getResult()
 
348
 
 
349
        somechannel = wFD(self.realm.createGroup(u"somechannel"))
 
350
        yield somechannel
 
351
        somechannel = somechannel.getResult()
 
352
 
 
353
        # Bring in one user, make sure he gets into the channel sanely
 
354
        user = TestCaseUserAgg(firstuser, self.realm, self.factory)
 
355
        self._login(user, "firstuser")
 
356
        user.transport.clear()
 
357
        user.write('JOIN #somechannel\r\n')
 
358
 
 
359
        response = self._response(user)
 
360
        self.assertEquals(len(response), 5)
 
361
 
 
362
        # Join message
 
363
        self.assertEquals(response[0][0], 'firstuser!firstuser@realmname')
 
364
        self.assertEquals(response[0][1], 'JOIN')
 
365
        self.assertEquals(response[0][2], ['#somechannel'])
 
366
 
 
367
        # User list
 
368
        self.assertEquals(response[1][1], '353')
 
369
        self.assertEquals(response[2][1], '366')
 
370
 
 
371
        # Topic (or lack thereof, as the case may be)
 
372
        self.assertEquals(response[3][1], '332')
 
373
        self.assertEquals(response[4][1], '333')
 
374
 
 
375
 
 
376
        # Hook up another client!  It is a CHAT SYSTEM!!!!!!!
 
377
        other = wFD(self._loggedInUser(u'otheruser'))
 
378
        yield other
 
379
        other = other.getResult()
 
380
 
 
381
        other.transport.clear()
 
382
        user.transport.clear()
 
383
        other.write('JOIN #somechannel\r\n')
 
384
 
 
385
        # At this point, both users should be in the channel
 
386
        response = self._response(other)
 
387
 
 
388
        event = self._response(user)
 
389
        self.assertEquals(len(event), 1)
 
390
        self.assertEquals(event[0][0], 'otheruser!otheruser@realmname')
 
391
        self.assertEquals(event[0][1], 'JOIN')
 
392
        self.assertEquals(event[0][2], ['#somechannel'])
 
393
 
 
394
        self.assertEquals(response[1][0], 'realmname')
 
395
        self.assertEquals(response[1][1], '353')
 
396
        self.assertEquals(response[1][2], ['otheruser', '=', '#somechannel', 'firstuser otheruser'])
 
397
    testJoin = dG(testJoin)
 
398
 
 
399
 
 
400
    def testLeave(self):
 
401
        user = wFD(self._loggedInUser(u'useruser'))
 
402
        yield user
 
403
        user = user.getResult()
 
404
 
 
405
        somechannel = wFD(self.realm.createGroup(u"somechannel"))
 
406
        yield somechannel
 
407
        somechannel = somechannel.getResult()
 
408
 
 
409
        user.write('JOIN #somechannel\r\n')
 
410
        user.transport.clear()
 
411
 
 
412
        other = wFD(self._loggedInUser(u'otheruser'))
 
413
        yield other
 
414
        other = other.getResult()
 
415
 
 
416
        other.write('JOIN #somechannel\r\n')
 
417
 
 
418
        user.transport.clear()
 
419
        other.transport.clear()
 
420
 
 
421
        user.write('PART #somechannel\r\n')
 
422
 
 
423
        response = self._response(user)
 
424
        event = self._response(other)
 
425
 
 
426
        self.assertEquals(len(response), 1)
 
427
        self.assertEquals(response[0][0], 'useruser!useruser@realmname')
 
428
        self.assertEquals(response[0][1], 'PART')
 
429
        self.assertEquals(response[0][2], ['#somechannel', 'leaving'])
 
430
        self.assertEquals(response, event)
 
431
 
 
432
        # Now again, with a part message
 
433
        user.write('JOIN #somechannel\r\n')
 
434
 
 
435
        user.transport.clear()
 
436
        other.transport.clear()
 
437
 
 
438
        user.write('PART #somechannel :goodbye stupidheads\r\n')
 
439
 
 
440
        response = self._response(user)
 
441
        event = self._response(other)
 
442
 
 
443
        self.assertEquals(len(response), 1)
 
444
        self.assertEquals(response[0][0], 'useruser!useruser@realmname')
 
445
        self.assertEquals(response[0][1], 'PART')
 
446
        self.assertEquals(response[0][2], ['#somechannel', 'goodbye stupidheads'])
 
447
        self.assertEquals(response, event)
 
448
    testLeave = dG(testLeave)
 
449
 
 
450
 
 
451
    def testGetTopic(self):
 
452
        user = wFD(self._loggedInUser(u'useruser'))
 
453
        yield user
 
454
        user = user.getResult()
 
455
 
 
456
        group = service.Group("somechannel")
 
457
        group.meta["topic"] = "This is a test topic."
 
458
        group.meta["topic_author"] = "some_fellow"
 
459
        group.meta["topic_date"] = 77777777
 
460
 
 
461
        add = wFD(self.realm.addGroup(group))
 
462
        yield add
 
463
        add.getResult()
 
464
 
 
465
        user.transport.clear()
 
466
        user.write("JOIN #somechannel\r\n")
 
467
 
 
468
        response = self._response(user)
 
469
 
 
470
        self.assertEquals(response[3][0], 'realmname')
 
471
        self.assertEquals(response[3][1], '332')
 
472
 
 
473
        # XXX Sigh.  irc.parsemsg() is not as correct as one might hope.
 
474
        self.assertEquals(response[3][2], ['useruser', '#somechannel', 'This is a test topic.'])
 
475
        self.assertEquals(response[4][1], '333')
 
476
        self.assertEquals(response[4][2], ['useruser', '#somechannel', 'some_fellow', '77777777'])
 
477
 
 
478
        user.transport.clear()
 
479
 
 
480
        user.write('TOPIC #somechannel\r\n')
 
481
 
 
482
        response = self._response(user)
 
483
 
 
484
        self.assertEquals(response[0][1], '332')
 
485
        self.assertEquals(response[0][2], ['useruser', '#somechannel', 'This is a test topic.'])
 
486
        self.assertEquals(response[1][1], '333')
 
487
        self.assertEquals(response[1][2], ['useruser', '#somechannel', 'some_fellow', '77777777'])
 
488
    testGetTopic = dG(testGetTopic)
 
489
 
 
490
 
 
491
    def testSetTopic(self):
 
492
        user = wFD(self._loggedInUser(u'useruser'))
 
493
        yield user
 
494
        user = user.getResult()
 
495
 
 
496
        add = wFD(self.realm.createGroup(u"somechannel"))
 
497
        yield add
 
498
        somechannel = add.getResult()
 
499
 
 
500
        user.write("JOIN #somechannel\r\n")
 
501
 
 
502
        other = wFD(self._loggedInUser(u'otheruser'))
 
503
        yield other
 
504
        other = other.getResult()
 
505
 
 
506
        other.write("JOIN #somechannel\r\n")
 
507
 
 
508
        user.transport.clear()
 
509
        other.transport.clear()
 
510
 
 
511
        other.write('TOPIC #somechannel :This is the new topic.\r\n')
 
512
 
 
513
        response = self._response(other)
 
514
        event = self._response(user)
 
515
 
 
516
        self.assertEquals(response, event)
 
517
 
 
518
        self.assertEquals(response[0][0], 'otheruser!otheruser@realmname')
 
519
        self.assertEquals(response[0][1], 'TOPIC')
 
520
        self.assertEquals(response[0][2], ['#somechannel', 'This is the new topic.'])
 
521
 
 
522
        other.transport.clear()
 
523
 
 
524
        somechannel.meta['topic_date'] = 12345
 
525
        other.write('TOPIC #somechannel\r\n')
 
526
 
 
527
        response = self._response(other)
 
528
        self.assertEquals(response[0][1], '332')
 
529
        self.assertEquals(response[0][2], ['otheruser', '#somechannel', 'This is the new topic.'])
 
530
        self.assertEquals(response[1][1], '333')
 
531
        self.assertEquals(response[1][2], ['otheruser', '#somechannel', 'otheruser', '12345'])
 
532
 
 
533
        other.transport.clear()
 
534
        other.write('TOPIC #asdlkjasd\r\n')
 
535
 
 
536
        response = self._response(other)
 
537
        self.assertEquals(response[0][1], '403')
 
538
    testSetTopic = dG(testSetTopic)
 
539
 
 
540
 
 
541
    def testGroupMessage(self):
 
542
        user = wFD(self._loggedInUser(u'useruser'))
 
543
        yield user
 
544
        user = user.getResult()
 
545
 
 
546
        add = wFD(self.realm.createGroup(u"somechannel"))
 
547
        yield add
 
548
        somechannel = add.getResult()
 
549
 
 
550
        user.write("JOIN #somechannel\r\n")
 
551
 
 
552
        other = wFD(self._loggedInUser(u'otheruser'))
 
553
        yield other
 
554
        other = other.getResult()
 
555
 
 
556
        other.write("JOIN #somechannel\r\n")
 
557
 
 
558
        user.transport.clear()
 
559
        other.transport.clear()
 
560
 
 
561
        user.write('PRIVMSG #somechannel :Hello, world.\r\n')
 
562
 
 
563
        response = self._response(user)
 
564
        event = self._response(other)
 
565
 
 
566
        self.failIf(response)
 
567
        self.assertEquals(len(event), 1)
 
568
        self.assertEquals(event[0][0], 'useruser!useruser@realmname')
 
569
        self.assertEquals(event[0][1], 'PRIVMSG', -1)
 
570
        self.assertEquals(event[0][2], ['#somechannel', 'Hello, world.'])
 
571
    testGroupMessage = dG(testGroupMessage)
 
572
 
 
573
 
 
574
    def testPrivateMessage(self):
 
575
        user = wFD(self._loggedInUser(u'useruser'))
 
576
        yield user
 
577
        user = user.getResult()
 
578
 
 
579
        other = wFD(self._loggedInUser(u'otheruser'))
 
580
        yield other
 
581
        other = other.getResult()
 
582
 
 
583
        user.transport.clear()
 
584
        other.transport.clear()
 
585
 
 
586
        user.write('PRIVMSG otheruser :Hello, monkey.\r\n')
 
587
 
 
588
        response = self._response(user)
 
589
        event = self._response(other)
 
590
 
 
591
        self.failIf(response)
 
592
        self.assertEquals(len(event), 1)
 
593
        self.assertEquals(event[0][0], 'useruser!useruser@realmname')
 
594
        self.assertEquals(event[0][1], 'PRIVMSG')
 
595
        self.assertEquals(event[0][2], ['otheruser', 'Hello, monkey.'])
 
596
 
 
597
        user.write('PRIVMSG nousernamedthis :Hello, monkey.\r\n')
 
598
 
 
599
        response = self._response(user)
 
600
 
 
601
        self.assertEquals(len(response), 1)
 
602
        self.assertEquals(response[0][0], 'realmname')
 
603
        self.assertEquals(response[0][1], '401')
 
604
        self.assertEquals(response[0][2], ['useruser', 'nousernamedthis', 'No such nick/channel.'])
 
605
    testPrivateMessage = dG(testPrivateMessage)
 
606
 
 
607
 
 
608
    def testOper(self):
 
609
        user = wFD(self._loggedInUser(u'useruser'))
 
610
        yield user
 
611
        user = user.getResult()
 
612
 
 
613
        user.transport.clear()
 
614
        user.write('OPER user pass\r\n')
 
615
        response = self._response(user)
 
616
 
 
617
        self.assertEquals(len(response), 1)
 
618
        self.assertEquals(response[0][1], '491')
 
619
    testOper = dG(testOper)
 
620
 
 
621
 
 
622
    def testGetUserMode(self):
 
623
        user = wFD(self._loggedInUser(u'useruser'))
 
624
        yield user
 
625
        user = user.getResult()
 
626
 
 
627
        user.transport.clear()
 
628
        user.write('MODE useruser\r\n')
 
629
 
 
630
        response = self._response(user)
 
631
        self.assertEquals(len(response), 1)
 
632
        self.assertEquals(response[0][0], 'realmname')
 
633
        self.assertEquals(response[0][1], '221')
 
634
        self.assertEquals(response[0][2], ['useruser', '+'])
 
635
    testGetUserMode = dG(testGetUserMode)
 
636
 
 
637
 
 
638
    def testSetUserMode(self):
 
639
        user = wFD(self._loggedInUser(u'useruser'))
 
640
        yield user
 
641
        user = user.getResult()
 
642
 
 
643
        user.transport.clear()
 
644
        user.write('MODE useruser +abcd\r\n')
 
645
 
 
646
        response = self._response(user)
 
647
        self.assertEquals(len(response), 1)
 
648
        self.assertEquals(response[0][1], '472')
 
649
    testSetUserMode = dG(testSetUserMode)
 
650
 
 
651
 
 
652
    def testGetGroupMode(self):
 
653
        user = wFD(self._loggedInUser(u'useruser'))
 
654
        yield user
 
655
        user = user.getResult()
 
656
 
 
657
        add = wFD(self.realm.createGroup(u"somechannel"))
 
658
        yield add
 
659
        somechannel = add.getResult()
 
660
 
 
661
        user.write('JOIN #somechannel\r\n')
 
662
 
 
663
        user.transport.clear()
 
664
        user.write('MODE #somechannel\r\n')
 
665
 
 
666
        response = self._response(user)
 
667
        self.assertEquals(len(response), 1)
 
668
        self.assertEquals(response[0][1], '324')
 
669
    testGetGroupMode = dG(testGetGroupMode)
 
670
 
 
671
 
 
672
    def testSetGroupMode(self):
 
673
        user = wFD(self._loggedInUser(u'useruser'))
 
674
        yield user
 
675
        user = user.getResult()
 
676
 
 
677
        group = wFD(self.realm.createGroup(u"groupname"))
 
678
        yield group
 
679
        group = group.getResult()
 
680
 
 
681
        user.write('JOIN #groupname\r\n')
 
682
 
 
683
        user.transport.clear()
 
684
        user.write('MODE #groupname +abcd\r\n')
 
685
 
 
686
        response = self._response(user)
 
687
        self.assertEquals(len(response), 1)
 
688
        self.assertEquals(response[0][1], '472')
 
689
    testSetGroupMode = dG(testSetGroupMode)
 
690
 
 
691
 
 
692
    def testWho(self):
 
693
        group = service.Group('groupname')
 
694
        add = wFD(self.realm.addGroup(group))
 
695
        yield add
 
696
        add.getResult()
 
697
 
 
698
        users = []
 
699
        for nick in u'userone', u'usertwo', u'userthree':
 
700
            u = wFD(self._loggedInUser(nick))
 
701
            yield u
 
702
            u = u.getResult()
 
703
            users.append(u)
 
704
            users[-1].write('JOIN #groupname\r\n')
 
705
        for user in users:
 
706
            user.transport.clear()
 
707
 
 
708
        users[0].write('WHO #groupname\r\n')
 
709
 
 
710
        r = self._response(users[0])
 
711
        self.failIf(self._response(users[1]))
 
712
        self.failIf(self._response(users[2]))
 
713
 
 
714
        wantusers = ['userone', 'usertwo', 'userthree']
 
715
        for (prefix, code, stuff) in r[:-1]:
 
716
            self.assertEquals(prefix, 'realmname')
 
717
            self.assertEquals(code, '352')
 
718
 
 
719
            (myname, group, theirname, theirhost, theirserver, theirnick, flag, extra) = stuff
 
720
            self.assertEquals(myname, 'userone')
 
721
            self.assertEquals(group, '#groupname')
 
722
            self.failUnless(theirname in wantusers)
 
723
            self.assertEquals(theirhost, 'realmname')
 
724
            self.assertEquals(theirserver, 'realmname')
 
725
            wantusers.remove(theirnick)
 
726
            self.assertEquals(flag, 'H')
 
727
            self.assertEquals(extra, '0 ' + theirnick)
 
728
        self.failIf(wantusers)
 
729
 
 
730
        prefix, code, stuff = r[-1]
 
731
        self.assertEquals(prefix, 'realmname')
 
732
        self.assertEquals(code, '315')
 
733
        myname, channel, extra = stuff
 
734
        self.assertEquals(myname, 'userone')
 
735
        self.assertEquals(channel, '#groupname')
 
736
        self.assertEquals(extra, 'End of /WHO list.')
 
737
    testWho = dG(testWho)
 
738
 
 
739
 
 
740
    def testList(self):
 
741
        user = wFD(self._loggedInUser(u"someuser"))
 
742
        yield user
 
743
        user = user.getResult()
 
744
        user.transport.clear()
 
745
 
 
746
        somegroup = wFD(self.realm.createGroup(u"somegroup"))
 
747
        yield somegroup
 
748
        somegroup = somegroup.getResult()
 
749
        somegroup.size = lambda: succeed(17)
 
750
        somegroup.meta['topic'] = 'this is the topic woo'
 
751
 
 
752
        # Test one group
 
753
        user.write('LIST #somegroup\r\n')
 
754
 
 
755
        r = self._response(user)
 
756
        self.assertEquals(len(r), 2)
 
757
        resp, end = r
 
758
 
 
759
        self.assertEquals(resp[0], 'realmname')
 
760
        self.assertEquals(resp[1], '322')
 
761
        self.assertEquals(resp[2][0], 'someuser')
 
762
        self.assertEquals(resp[2][1], 'somegroup')
 
763
        self.assertEquals(resp[2][2], '17')
 
764
        self.assertEquals(resp[2][3], 'this is the topic woo')
 
765
 
 
766
        self.assertEquals(end[0], 'realmname')
 
767
        self.assertEquals(end[1], '323')
 
768
        self.assertEquals(end[2][0], 'someuser')
 
769
        self.assertEquals(end[2][1], 'End of /LIST')
 
770
 
 
771
        user.transport.clear()
 
772
        # Test all groups
 
773
 
 
774
        user.write('LIST\r\n')
 
775
        r = self._response(user)
 
776
        self.assertEquals(len(r), 2)
 
777
 
 
778
        fg1, end = r
 
779
 
 
780
        self.assertEquals(fg1[1], '322')
 
781
        self.assertEquals(fg1[2][1], 'somegroup')
 
782
        self.assertEquals(fg1[2][2], '17')
 
783
        self.assertEquals(fg1[2][3], 'this is the topic woo')
 
784
 
 
785
        self.assertEquals(end[1], '323')
 
786
    testList = dG(testList)
 
787
 
 
788
 
 
789
    def testWhois(self):
 
790
        user = wFD(self._loggedInUser(u'someguy'))
 
791
        yield user
 
792
        user = user.getResult()
 
793
 
 
794
        otherguy = service.User("otherguy")
 
795
        otherguy.itergroups = lambda: iter([
 
796
            service.Group('groupA'),
 
797
            service.Group('groupB')])
 
798
        otherguy.signOn = 10
 
799
        otherguy.lastMessage = time.time() - 15
 
800
 
 
801
        add = wFD(self.realm.addUser(otherguy))
 
802
        yield add
 
803
        add.getResult()
 
804
 
 
805
        user.transport.clear()
 
806
        user.write('WHOIS otherguy\r\n')
 
807
        r = self._response(user)
 
808
 
 
809
        self.assertEquals(len(r), 5)
 
810
        wuser, wserver, idle, channels, end = r
 
811
 
 
812
        self.assertEquals(wuser[0], 'realmname')
 
813
        self.assertEquals(wuser[1], '311')
 
814
        self.assertEquals(wuser[2][0], 'someguy')
 
815
        self.assertEquals(wuser[2][1], 'otherguy')
 
816
        self.assertEquals(wuser[2][2], 'otherguy')
 
817
        self.assertEquals(wuser[2][3], 'realmname')
 
818
        self.assertEquals(wuser[2][4], '*')
 
819
        self.assertEquals(wuser[2][5], 'otherguy')
 
820
 
 
821
        self.assertEquals(wserver[0], 'realmname')
 
822
        self.assertEquals(wserver[1], '312')
 
823
        self.assertEquals(wserver[2][0], 'someguy')
 
824
        self.assertEquals(wserver[2][1], 'otherguy')
 
825
        self.assertEquals(wserver[2][2], 'realmname')
 
826
        self.assertEquals(wserver[2][3], 'Hi mom!')
 
827
 
 
828
        self.assertEquals(idle[0], 'realmname')
 
829
        self.assertEquals(idle[1], '317')
 
830
        self.assertEquals(idle[2][0], 'someguy')
 
831
        self.assertEquals(idle[2][1], 'otherguy')
 
832
        self.assertEquals(idle[2][2], '15')
 
833
        self.assertEquals(idle[2][3], '10')
 
834
        self.assertEquals(idle[2][4], "seconds idle, signon time")
 
835
 
 
836
        self.assertEquals(channels[0], 'realmname')
 
837
        self.assertEquals(channels[1], '319')
 
838
        self.assertEquals(channels[2][0], 'someguy')
 
839
        self.assertEquals(channels[2][1], 'otherguy')
 
840
        self.assertEquals(channels[2][2], '#groupA #groupB')
 
841
 
 
842
        self.assertEquals(end[0], 'realmname')
 
843
        self.assertEquals(end[1], '318')
 
844
        self.assertEquals(end[2][0], 'someguy')
 
845
        self.assertEquals(end[2][1], 'otherguy')
 
846
        self.assertEquals(end[2][2], 'End of WHOIS list.')
 
847
    testWhois = dG(testWhois)
 
848
 
 
849
 
 
850
class TestMind(service.PBMind):
 
851
    def __init__(self, *a, **kw):
 
852
        self.joins = []
 
853
        self.parts = []
 
854
        self.messages = []
 
855
        self.meta = []
 
856
 
 
857
    def remote_userJoined(self, user, group):
 
858
        self.joins.append((user, group))
 
859
 
 
860
    def remote_userLeft(self, user, group, reason):
 
861
        self.parts.append((user, group, reason))
 
862
 
 
863
    def remote_receive(self, sender, recipient, message):
 
864
        self.messages.append((sender, recipient, message))
 
865
 
 
866
    def remote_groupMetaUpdate(self, group, meta):
 
867
        self.meta.append((group, meta))
 
868
pb.setUnjellyableForClass(TestMind, service.PBMindReference)
 
869
 
 
870
 
 
871
class PBProtocolTestCase(unittest.TestCase):
 
872
    def setUp(self):
 
873
        self.realm = service.InMemoryWordsRealm("realmname")
 
874
        self.checker = checkers.InMemoryUsernamePasswordDatabaseDontUse()
 
875
        self.portal = portal.Portal(
 
876
            self.realm, [self.checker])
 
877
        self.serverFactory = pb.PBServerFactory(self.portal)
 
878
        self.serverFactory.protocol = self._protocolFactory
 
879
        self.serverFactory.unsafeTracebacks = True
 
880
        self.clientFactory = pb.PBClientFactory()
 
881
        self.clientFactory.unsafeTracebacks = True
 
882
        self.serverPort = reactor.listenTCP(0, self.serverFactory)
 
883
        self.clientConn = reactor.connectTCP(
 
884
            '127.0.0.1',
 
885
            self.serverPort.getHost().port,
 
886
            self.clientFactory)
 
887
 
 
888
    def _protocolFactory(self, *args, **kw):
 
889
        self._serverProtocol = pb.Broker(0)
 
890
        return self._serverProtocol
 
891
 
 
892
    def tearDown(self):
 
893
        d3 = Deferred()
 
894
        self._serverProtocol.notifyOnDisconnect(lambda: d3.callback(None))
 
895
        return DeferredList([
 
896
            maybeDeferred(self.serverPort.stopListening),
 
897
            maybeDeferred(self.clientConn.disconnect), d3])
 
898
 
 
899
    def _loggedInAvatar(self, name, password, mind):
 
900
        creds = credentials.UsernamePassword(name, password)
 
901
        self.checker.addUser(name.encode('ascii'), password)
 
902
        d = self.realm.createUser(name)
 
903
        d.addCallback(lambda ign: self.clientFactory.login(creds, mind))
 
904
        return d
 
905
 
 
906
    def testGroups(self):
 
907
        mindone = TestMind()
 
908
        one = wFD(self._loggedInAvatar(u"one", "p1", mindone))
 
909
        yield one
 
910
        one = one.getResult()
 
911
 
 
912
        mindtwo = TestMind()
 
913
        two = wFD(self._loggedInAvatar(u"two", "p2", mindtwo))
 
914
        yield two
 
915
        two = two.getResult()
 
916
 
 
917
        add = wFD(self.realm.createGroup(u"foobar"))
 
918
        yield add
 
919
        add.getResult()
 
920
 
 
921
        groupone = wFD(one.join(u"foobar"))
 
922
        yield groupone
 
923
        groupone = groupone.getResult()
 
924
 
 
925
        grouptwo = wFD(two.join(u"foobar"))
 
926
        yield grouptwo
 
927
        grouptwo = grouptwo.getResult()
 
928
 
 
929
        msg = wFD(groupone.send({"text": "hello, monkeys"}))
 
930
        yield msg
 
931
        msg = msg.getResult()
 
932
 
 
933
        leave = wFD(groupone.leave())
 
934
        yield leave
 
935
        leave = leave.getResult()
 
936
    testGroups = dG(testGroups)