~ntt-pf-lab/nova/monkey_patch_notification

« back to all changes in this revision

Viewing changes to vendor/Twisted-10.0.0/twisted/words/test/test_service.py

  • Committer: Jesse Andrews
  • Date: 2010-05-28 06:05:26 UTC
  • Revision ID: git-v1:bf6e6e718cdc7488e2da87b21e258ccc065fe499
initial commit

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
# Copyright (c) 2009 Twisted Matrix Laboratories.
 
2
# See LICENSE for details.
 
3
 
 
4
"""
 
5
Tests for L{twisted.words.service}.
 
6
"""
 
7
 
 
8
import time
 
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, 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
 
 
217
    def login(self, credentials, mind, *interfaces):
 
218
        d = Deferred()
 
219
        self.logins.append((credentials, mind, interfaces, d))
 
220
        return d
 
221
 
 
222
 
 
223
class TestCaseUserAgg(object):
 
224
    def __init__(self, user, realm, factory, address=address.IPv4Address('TCP', '127.0.0.1', 54321)):
 
225
        self.user = user
 
226
        self.transport = proto_helpers.StringTransportWithDisconnection()
 
227
        self.protocol = factory.buildProtocol(address)
 
228
        self.transport.protocol = self.protocol
 
229
        self.user.mind = self.protocol
 
230
        self.protocol.makeConnection(self.transport)
 
231
 
 
232
 
 
233
    def write(self, stuff):
 
234
        if isinstance(stuff, unicode):
 
235
            stuff = stuff.encode('utf-8')
 
236
        self.protocol.dataReceived(stuff)
 
237
 
 
238
 
 
239
class IRCProtocolTestCase(unittest.TestCase):
 
240
    STATIC_USERS = [
 
241
        u'useruser', u'otheruser', u'someguy', u'firstuser', u'username',
 
242
        u'userone', u'usertwo', u'userthree', u'someuser']
 
243
 
 
244
 
 
245
    def setUp(self):
 
246
        self.realm = service.InMemoryWordsRealm("realmname")
 
247
        self.checker = checkers.InMemoryUsernamePasswordDatabaseDontUse()
 
248
        self.portal = portal.Portal(self.realm, [self.checker])
 
249
        self.factory = service.IRCFactory(self.realm, self.portal)
 
250
 
 
251
        c = []
 
252
        for nick in self.STATIC_USERS:
 
253
            c.append(self.realm.createUser(nick))
 
254
            self.checker.addUser(nick.encode('ascii'), nick + "_password")
 
255
        return DeferredList(c)
 
256
 
 
257
 
 
258
    def _assertGreeting(self, user):
 
259
        """
 
260
        The user has been greeted with the four messages that are (usually)
 
261
        considered to start an IRC session.
 
262
        
 
263
        Asserts that the required responses were received.
 
264
        """
 
265
        # Make sure we get 1-4 at least
 
266
        response = self._response(user)
 
267
        expected = [irc.RPL_WELCOME, irc.RPL_YOURHOST, irc.RPL_CREATED,
 
268
                    irc.RPL_MYINFO]
 
269
        for (prefix, command, args) in response:
 
270
            if command in expected:
 
271
                expected.remove(command)
 
272
        self.failIf(expected, "Missing responses for %r" % (expected,))
 
273
 
 
274
 
 
275
    def _login(self, user, nick, password=None):
 
276
        if password is None:
 
277
            password = nick + "_password"
 
278
        user.write('PASS %s\r\n' % (password,))
 
279
        user.write('NICK %s extrainfo\r\n' % (nick,))
 
280
 
 
281
 
 
282
    def _loggedInUser(self, name):
 
283
        d = wFD(self.realm.lookupUser(name))
 
284
        yield d
 
285
        user = d.getResult()
 
286
        agg = TestCaseUserAgg(user, self.realm, self.factory)
 
287
        self._login(agg, name)
 
288
        yield agg
 
289
    _loggedInUser = dG(_loggedInUser)
 
290
 
 
291
 
 
292
    def _response(self, user, messageType=None):
 
293
        """
 
294
        Extracts the user's response, and returns a list of parsed lines.
 
295
        If messageType is defined, only messages of that type will be returned.
 
296
        """
 
297
        response = user.transport.value().splitlines()
 
298
        user.transport.clear()
 
299
        result = []
 
300
        for message in map(irc.parsemsg, response):
 
301
            if messageType is None or message[1] == messageType:
 
302
                result.append(message)
 
303
        return result
 
304
 
 
305
 
 
306
    def testPASSLogin(self):
 
307
        user = wFD(self._loggedInUser(u'firstuser'))
 
308
        yield user
 
309
        user = user.getResult()
 
310
        self._assertGreeting(user)
 
311
    testPASSLogin = dG(testPASSLogin)
 
312
 
 
313
 
 
314
    def test_nickServLogin(self):
 
315
        """
 
316
        Sending NICK without PASS will prompt the user for their password.
 
317
        When the user sends their password to NickServ, it will respond with a
 
318
        Greeting.
 
319
        """
 
320
        firstuser = wFD(self.realm.lookupUser(u'firstuser'))
 
321
        yield firstuser
 
322
        firstuser = firstuser.getResult()
 
323
 
 
324
        user = TestCaseUserAgg(firstuser, self.realm, self.factory)
 
325
        user.write('NICK firstuser extrainfo\r\n')
 
326
        response = self._response(user, 'PRIVMSG')
 
327
        self.assertEquals(len(response), 1)
 
328
        self.assertEquals(response[0][0], service.NICKSERV)
 
329
        self.assertEquals(response[0][1], 'PRIVMSG')
 
330
        self.assertEquals(response[0][2], ['firstuser', 'Password?'])
 
331
        user.transport.clear()
 
332
 
 
333
        user.write('PRIVMSG nickserv firstuser_password\r\n')
 
334
        self._assertGreeting(user)
 
335
    test_nickServLogin = dG(test_nickServLogin)
 
336
 
 
337
 
 
338
    def testFailedLogin(self):
 
339
        firstuser = wFD(self.realm.lookupUser(u'firstuser'))
 
340
        yield firstuser
 
341
        firstuser = firstuser.getResult()
 
342
 
 
343
        user = TestCaseUserAgg(firstuser, self.realm, self.factory)
 
344
        self._login(user, "firstuser", "wrongpass")
 
345
        response = self._response(user, "PRIVMSG")
 
346
        self.assertEquals(len(response), 1)
 
347
        self.assertEquals(response[0][2], ['firstuser', 'Login failed.  Goodbye.'])
 
348
    testFailedLogin = dG(testFailedLogin)
 
349
 
 
350
 
 
351
    def testLogout(self):
 
352
        logout = []
 
353
        firstuser = wFD(self.realm.lookupUser(u'firstuser'))
 
354
        yield firstuser
 
355
        firstuser = firstuser.getResult()
 
356
 
 
357
        user = TestCaseUserAgg(firstuser, self.realm, self.factory)
 
358
        self._login(user, "firstuser")
 
359
        user.protocol.logout = lambda: logout.append(True)
 
360
        user.write('QUIT\r\n')
 
361
        self.assertEquals(logout, [True])
 
362
    testLogout = dG(testLogout)
 
363
 
 
364
 
 
365
    def testJoin(self):
 
366
        firstuser = wFD(self.realm.lookupUser(u'firstuser'))
 
367
        yield firstuser
 
368
        firstuser = firstuser.getResult()
 
369
 
 
370
        somechannel = wFD(self.realm.createGroup(u"somechannel"))
 
371
        yield somechannel
 
372
        somechannel = somechannel.getResult()
 
373
 
 
374
        somechannel.meta['topic'] = 'some random topic'
 
375
 
 
376
        # Bring in one user, make sure he gets into the channel sanely
 
377
        user = TestCaseUserAgg(firstuser, self.realm, self.factory)
 
378
        self._login(user, "firstuser")
 
379
        user.transport.clear()
 
380
        user.write('JOIN #somechannel\r\n')
 
381
 
 
382
        response = self._response(user)
 
383
        self.assertEquals(len(response), 5)
 
384
 
 
385
        # Join message
 
386
        self.assertEquals(response[0][0], 'firstuser!firstuser@realmname')
 
387
        self.assertEquals(response[0][1], 'JOIN')
 
388
        self.assertEquals(response[0][2], ['#somechannel'])
 
389
 
 
390
        # User list
 
391
        self.assertEquals(response[1][1], '353')
 
392
        self.assertEquals(response[2][1], '366')
 
393
 
 
394
        # Topic (or lack thereof, as the case may be)
 
395
        self.assertEquals(response[3][1], '332')
 
396
        self.assertEquals(response[4][1], '333')
 
397
 
 
398
 
 
399
        # Hook up another client!  It is a CHAT SYSTEM!!!!!!!
 
400
        other = wFD(self._loggedInUser(u'otheruser'))
 
401
        yield other
 
402
        other = other.getResult()
 
403
 
 
404
        other.transport.clear()
 
405
        user.transport.clear()
 
406
        other.write('JOIN #somechannel\r\n')
 
407
 
 
408
        # At this point, both users should be in the channel
 
409
        response = self._response(other)
 
410
 
 
411
        event = self._response(user)
 
412
        self.assertEquals(len(event), 1)
 
413
        self.assertEquals(event[0][0], 'otheruser!otheruser@realmname')
 
414
        self.assertEquals(event[0][1], 'JOIN')
 
415
        self.assertEquals(event[0][2], ['#somechannel'])
 
416
 
 
417
        self.assertEquals(response[1][0], 'realmname')
 
418
        self.assertEquals(response[1][1], '353')
 
419
        self.assertEquals(response[1][2], ['otheruser', '=', '#somechannel', 'firstuser otheruser'])
 
420
    testJoin = dG(testJoin)
 
421
 
 
422
 
 
423
    def test_joinTopicless(self):
 
424
        """
 
425
        When a user joins a group without a topic, no topic information is
 
426
        sent to that user.
 
427
        """
 
428
        firstuser = wFD(self.realm.lookupUser(u'firstuser'))
 
429
        yield firstuser
 
430
        firstuser = firstuser.getResult()
 
431
 
 
432
        somechannel = wFD(self.realm.createGroup(u"somechannel"))
 
433
        yield somechannel
 
434
        somechannel = somechannel.getResult()
 
435
 
 
436
        # Bring in one user, make sure he gets into the channel sanely
 
437
        user = TestCaseUserAgg(firstuser, self.realm, self.factory)
 
438
        self._login(user, "firstuser")
 
439
        user.transport.clear()
 
440
        user.write('JOIN #somechannel\r\n')
 
441
 
 
442
        response = self._response(user)
 
443
        responseCodes = [r[1] for r in response]
 
444
        self.assertNotIn('332', responseCodes)
 
445
        self.assertNotIn('333', responseCodes)
 
446
    test_joinTopicless = dG(test_joinTopicless)
 
447
 
 
448
 
 
449
    def testLeave(self):
 
450
        user = wFD(self._loggedInUser(u'useruser'))
 
451
        yield user
 
452
        user = user.getResult()
 
453
 
 
454
        somechannel = wFD(self.realm.createGroup(u"somechannel"))
 
455
        yield somechannel
 
456
        somechannel = somechannel.getResult()
 
457
 
 
458
        user.write('JOIN #somechannel\r\n')
 
459
        user.transport.clear()
 
460
 
 
461
        other = wFD(self._loggedInUser(u'otheruser'))
 
462
        yield other
 
463
        other = other.getResult()
 
464
 
 
465
        other.write('JOIN #somechannel\r\n')
 
466
 
 
467
        user.transport.clear()
 
468
        other.transport.clear()
 
469
 
 
470
        user.write('PART #somechannel\r\n')
 
471
 
 
472
        response = self._response(user)
 
473
        event = self._response(other)
 
474
 
 
475
        self.assertEquals(len(response), 1)
 
476
        self.assertEquals(response[0][0], 'useruser!useruser@realmname')
 
477
        self.assertEquals(response[0][1], 'PART')
 
478
        self.assertEquals(response[0][2], ['#somechannel', 'leaving'])
 
479
        self.assertEquals(response, event)
 
480
 
 
481
        # Now again, with a part message
 
482
        user.write('JOIN #somechannel\r\n')
 
483
 
 
484
        user.transport.clear()
 
485
        other.transport.clear()
 
486
 
 
487
        user.write('PART #somechannel :goodbye stupidheads\r\n')
 
488
 
 
489
        response = self._response(user)
 
490
        event = self._response(other)
 
491
 
 
492
        self.assertEquals(len(response), 1)
 
493
        self.assertEquals(response[0][0], 'useruser!useruser@realmname')
 
494
        self.assertEquals(response[0][1], 'PART')
 
495
        self.assertEquals(response[0][2], ['#somechannel', 'goodbye stupidheads'])
 
496
        self.assertEquals(response, event)
 
497
    testLeave = dG(testLeave)
 
498
 
 
499
 
 
500
    def testGetTopic(self):
 
501
        user = wFD(self._loggedInUser(u'useruser'))
 
502
        yield user
 
503
        user = user.getResult()
 
504
 
 
505
        group = service.Group("somechannel")
 
506
        group.meta["topic"] = "This is a test topic."
 
507
        group.meta["topic_author"] = "some_fellow"
 
508
        group.meta["topic_date"] = 77777777
 
509
 
 
510
        add = wFD(self.realm.addGroup(group))
 
511
        yield add
 
512
        add.getResult()
 
513
 
 
514
        user.transport.clear()
 
515
        user.write("JOIN #somechannel\r\n")
 
516
 
 
517
        response = self._response(user)
 
518
 
 
519
        self.assertEquals(response[3][0], 'realmname')
 
520
        self.assertEquals(response[3][1], '332')
 
521
 
 
522
        # XXX Sigh.  irc.parsemsg() is not as correct as one might hope.
 
523
        self.assertEquals(response[3][2], ['useruser', '#somechannel', 'This is a test topic.'])
 
524
        self.assertEquals(response[4][1], '333')
 
525
        self.assertEquals(response[4][2], ['useruser', '#somechannel', 'some_fellow', '77777777'])
 
526
 
 
527
        user.transport.clear()
 
528
 
 
529
        user.write('TOPIC #somechannel\r\n')
 
530
 
 
531
        response = self._response(user)
 
532
 
 
533
        self.assertEquals(response[0][1], '332')
 
534
        self.assertEquals(response[0][2], ['useruser', '#somechannel', 'This is a test topic.'])
 
535
        self.assertEquals(response[1][1], '333')
 
536
        self.assertEquals(response[1][2], ['useruser', '#somechannel', 'some_fellow', '77777777'])
 
537
    testGetTopic = dG(testGetTopic)
 
538
 
 
539
 
 
540
    def testSetTopic(self):
 
541
        user = wFD(self._loggedInUser(u'useruser'))
 
542
        yield user
 
543
        user = user.getResult()
 
544
 
 
545
        add = wFD(self.realm.createGroup(u"somechannel"))
 
546
        yield add
 
547
        somechannel = add.getResult()
 
548
 
 
549
        user.write("JOIN #somechannel\r\n")
 
550
 
 
551
        other = wFD(self._loggedInUser(u'otheruser'))
 
552
        yield other
 
553
        other = other.getResult()
 
554
 
 
555
        other.write("JOIN #somechannel\r\n")
 
556
 
 
557
        user.transport.clear()
 
558
        other.transport.clear()
 
559
 
 
560
        other.write('TOPIC #somechannel :This is the new topic.\r\n')
 
561
 
 
562
        response = self._response(other)
 
563
        event = self._response(user)
 
564
 
 
565
        self.assertEquals(response, event)
 
566
 
 
567
        self.assertEquals(response[0][0], 'otheruser!otheruser@realmname')
 
568
        self.assertEquals(response[0][1], 'TOPIC')
 
569
        self.assertEquals(response[0][2], ['#somechannel', 'This is the new topic.'])
 
570
 
 
571
        other.transport.clear()
 
572
 
 
573
        somechannel.meta['topic_date'] = 12345
 
574
        other.write('TOPIC #somechannel\r\n')
 
575
 
 
576
        response = self._response(other)
 
577
        self.assertEquals(response[0][1], '332')
 
578
        self.assertEquals(response[0][2], ['otheruser', '#somechannel', 'This is the new topic.'])
 
579
        self.assertEquals(response[1][1], '333')
 
580
        self.assertEquals(response[1][2], ['otheruser', '#somechannel', 'otheruser', '12345'])
 
581
 
 
582
        other.transport.clear()
 
583
        other.write('TOPIC #asdlkjasd\r\n')
 
584
 
 
585
        response = self._response(other)
 
586
        self.assertEquals(response[0][1], '403')
 
587
    testSetTopic = dG(testSetTopic)
 
588
 
 
589
 
 
590
    def testGroupMessage(self):
 
591
        user = wFD(self._loggedInUser(u'useruser'))
 
592
        yield user
 
593
        user = user.getResult()
 
594
 
 
595
        add = wFD(self.realm.createGroup(u"somechannel"))
 
596
        yield add
 
597
        somechannel = add.getResult()
 
598
 
 
599
        user.write("JOIN #somechannel\r\n")
 
600
 
 
601
        other = wFD(self._loggedInUser(u'otheruser'))
 
602
        yield other
 
603
        other = other.getResult()
 
604
 
 
605
        other.write("JOIN #somechannel\r\n")
 
606
 
 
607
        user.transport.clear()
 
608
        other.transport.clear()
 
609
 
 
610
        user.write('PRIVMSG #somechannel :Hello, world.\r\n')
 
611
 
 
612
        response = self._response(user)
 
613
        event = self._response(other)
 
614
 
 
615
        self.failIf(response)
 
616
        self.assertEquals(len(event), 1)
 
617
        self.assertEquals(event[0][0], 'useruser!useruser@realmname')
 
618
        self.assertEquals(event[0][1], 'PRIVMSG', -1)
 
619
        self.assertEquals(event[0][2], ['#somechannel', 'Hello, world.'])
 
620
    testGroupMessage = dG(testGroupMessage)
 
621
 
 
622
 
 
623
    def testPrivateMessage(self):
 
624
        user = wFD(self._loggedInUser(u'useruser'))
 
625
        yield user
 
626
        user = user.getResult()
 
627
 
 
628
        other = wFD(self._loggedInUser(u'otheruser'))
 
629
        yield other
 
630
        other = other.getResult()
 
631
 
 
632
        user.transport.clear()
 
633
        other.transport.clear()
 
634
 
 
635
        user.write('PRIVMSG otheruser :Hello, monkey.\r\n')
 
636
 
 
637
        response = self._response(user)
 
638
        event = self._response(other)
 
639
 
 
640
        self.failIf(response)
 
641
        self.assertEquals(len(event), 1)
 
642
        self.assertEquals(event[0][0], 'useruser!useruser@realmname')
 
643
        self.assertEquals(event[0][1], 'PRIVMSG')
 
644
        self.assertEquals(event[0][2], ['otheruser', 'Hello, monkey.'])
 
645
 
 
646
        user.write('PRIVMSG nousernamedthis :Hello, monkey.\r\n')
 
647
 
 
648
        response = self._response(user)
 
649
 
 
650
        self.assertEquals(len(response), 1)
 
651
        self.assertEquals(response[0][0], 'realmname')
 
652
        self.assertEquals(response[0][1], '401')
 
653
        self.assertEquals(response[0][2], ['useruser', 'nousernamedthis', 'No such nick/channel.'])
 
654
    testPrivateMessage = dG(testPrivateMessage)
 
655
 
 
656
 
 
657
    def testOper(self):
 
658
        user = wFD(self._loggedInUser(u'useruser'))
 
659
        yield user
 
660
        user = user.getResult()
 
661
 
 
662
        user.transport.clear()
 
663
        user.write('OPER user pass\r\n')
 
664
        response = self._response(user)
 
665
 
 
666
        self.assertEquals(len(response), 1)
 
667
        self.assertEquals(response[0][1], '491')
 
668
    testOper = dG(testOper)
 
669
 
 
670
 
 
671
    def testGetUserMode(self):
 
672
        user = wFD(self._loggedInUser(u'useruser'))
 
673
        yield user
 
674
        user = user.getResult()
 
675
 
 
676
        user.transport.clear()
 
677
        user.write('MODE useruser\r\n')
 
678
 
 
679
        response = self._response(user)
 
680
        self.assertEquals(len(response), 1)
 
681
        self.assertEquals(response[0][0], 'realmname')
 
682
        self.assertEquals(response[0][1], '221')
 
683
        self.assertEquals(response[0][2], ['useruser', '+'])
 
684
    testGetUserMode = dG(testGetUserMode)
 
685
 
 
686
 
 
687
    def testSetUserMode(self):
 
688
        user = wFD(self._loggedInUser(u'useruser'))
 
689
        yield user
 
690
        user = user.getResult()
 
691
 
 
692
        user.transport.clear()
 
693
        user.write('MODE useruser +abcd\r\n')
 
694
 
 
695
        response = self._response(user)
 
696
        self.assertEquals(len(response), 1)
 
697
        self.assertEquals(response[0][1], '472')
 
698
    testSetUserMode = dG(testSetUserMode)
 
699
 
 
700
 
 
701
    def testGetGroupMode(self):
 
702
        user = wFD(self._loggedInUser(u'useruser'))
 
703
        yield user
 
704
        user = user.getResult()
 
705
 
 
706
        add = wFD(self.realm.createGroup(u"somechannel"))
 
707
        yield add
 
708
        somechannel = add.getResult()
 
709
 
 
710
        user.write('JOIN #somechannel\r\n')
 
711
 
 
712
        user.transport.clear()
 
713
        user.write('MODE #somechannel\r\n')
 
714
 
 
715
        response = self._response(user)
 
716
        self.assertEquals(len(response), 1)
 
717
        self.assertEquals(response[0][1], '324')
 
718
    testGetGroupMode = dG(testGetGroupMode)
 
719
 
 
720
 
 
721
    def testSetGroupMode(self):
 
722
        user = wFD(self._loggedInUser(u'useruser'))
 
723
        yield user
 
724
        user = user.getResult()
 
725
 
 
726
        group = wFD(self.realm.createGroup(u"groupname"))
 
727
        yield group
 
728
        group = group.getResult()
 
729
 
 
730
        user.write('JOIN #groupname\r\n')
 
731
 
 
732
        user.transport.clear()
 
733
        user.write('MODE #groupname +abcd\r\n')
 
734
 
 
735
        response = self._response(user)
 
736
        self.assertEquals(len(response), 1)
 
737
        self.assertEquals(response[0][1], '472')
 
738
    testSetGroupMode = dG(testSetGroupMode)
 
739
 
 
740
 
 
741
    def testWho(self):
 
742
        group = service.Group('groupname')
 
743
        add = wFD(self.realm.addGroup(group))
 
744
        yield add
 
745
        add.getResult()
 
746
 
 
747
        users = []
 
748
        for nick in u'userone', u'usertwo', u'userthree':
 
749
            u = wFD(self._loggedInUser(nick))
 
750
            yield u
 
751
            u = u.getResult()
 
752
            users.append(u)
 
753
            users[-1].write('JOIN #groupname\r\n')
 
754
        for user in users:
 
755
            user.transport.clear()
 
756
 
 
757
        users[0].write('WHO #groupname\r\n')
 
758
 
 
759
        r = self._response(users[0])
 
760
        self.failIf(self._response(users[1]))
 
761
        self.failIf(self._response(users[2]))
 
762
 
 
763
        wantusers = ['userone', 'usertwo', 'userthree']
 
764
        for (prefix, code, stuff) in r[:-1]:
 
765
            self.assertEquals(prefix, 'realmname')
 
766
            self.assertEquals(code, '352')
 
767
 
 
768
            (myname, group, theirname, theirhost, theirserver, theirnick, flag, extra) = stuff
 
769
            self.assertEquals(myname, 'userone')
 
770
            self.assertEquals(group, '#groupname')
 
771
            self.failUnless(theirname in wantusers)
 
772
            self.assertEquals(theirhost, 'realmname')
 
773
            self.assertEquals(theirserver, 'realmname')
 
774
            wantusers.remove(theirnick)
 
775
            self.assertEquals(flag, 'H')
 
776
            self.assertEquals(extra, '0 ' + theirnick)
 
777
        self.failIf(wantusers)
 
778
 
 
779
        prefix, code, stuff = r[-1]
 
780
        self.assertEquals(prefix, 'realmname')
 
781
        self.assertEquals(code, '315')
 
782
        myname, channel, extra = stuff
 
783
        self.assertEquals(myname, 'userone')
 
784
        self.assertEquals(channel, '#groupname')
 
785
        self.assertEquals(extra, 'End of /WHO list.')
 
786
    testWho = dG(testWho)
 
787
 
 
788
 
 
789
    def testList(self):
 
790
        user = wFD(self._loggedInUser(u"someuser"))
 
791
        yield user
 
792
        user = user.getResult()
 
793
        user.transport.clear()
 
794
 
 
795
        somegroup = wFD(self.realm.createGroup(u"somegroup"))
 
796
        yield somegroup
 
797
        somegroup = somegroup.getResult()
 
798
        somegroup.size = lambda: succeed(17)
 
799
        somegroup.meta['topic'] = 'this is the topic woo'
 
800
 
 
801
        # Test one group
 
802
        user.write('LIST #somegroup\r\n')
 
803
 
 
804
        r = self._response(user)
 
805
        self.assertEquals(len(r), 2)
 
806
        resp, end = r
 
807
 
 
808
        self.assertEquals(resp[0], 'realmname')
 
809
        self.assertEquals(resp[1], '322')
 
810
        self.assertEquals(resp[2][0], 'someuser')
 
811
        self.assertEquals(resp[2][1], 'somegroup')
 
812
        self.assertEquals(resp[2][2], '17')
 
813
        self.assertEquals(resp[2][3], 'this is the topic woo')
 
814
 
 
815
        self.assertEquals(end[0], 'realmname')
 
816
        self.assertEquals(end[1], '323')
 
817
        self.assertEquals(end[2][0], 'someuser')
 
818
        self.assertEquals(end[2][1], 'End of /LIST')
 
819
 
 
820
        user.transport.clear()
 
821
        # Test all groups
 
822
 
 
823
        user.write('LIST\r\n')
 
824
        r = self._response(user)
 
825
        self.assertEquals(len(r), 2)
 
826
 
 
827
        fg1, end = r
 
828
 
 
829
        self.assertEquals(fg1[1], '322')
 
830
        self.assertEquals(fg1[2][1], 'somegroup')
 
831
        self.assertEquals(fg1[2][2], '17')
 
832
        self.assertEquals(fg1[2][3], 'this is the topic woo')
 
833
 
 
834
        self.assertEquals(end[1], '323')
 
835
    testList = dG(testList)
 
836
 
 
837
 
 
838
    def testWhois(self):
 
839
        user = wFD(self._loggedInUser(u'someguy'))
 
840
        yield user
 
841
        user = user.getResult()
 
842
 
 
843
        otherguy = service.User("otherguy")
 
844
        otherguy.itergroups = lambda: iter([
 
845
            service.Group('groupA'),
 
846
            service.Group('groupB')])
 
847
        otherguy.signOn = 10
 
848
        otherguy.lastMessage = time.time() - 15
 
849
 
 
850
        add = wFD(self.realm.addUser(otherguy))
 
851
        yield add
 
852
        add.getResult()
 
853
 
 
854
        user.transport.clear()
 
855
        user.write('WHOIS otherguy\r\n')
 
856
        r = self._response(user)
 
857
 
 
858
        self.assertEquals(len(r), 5)
 
859
        wuser, wserver, idle, channels, end = r
 
860
 
 
861
        self.assertEquals(wuser[0], 'realmname')
 
862
        self.assertEquals(wuser[1], '311')
 
863
        self.assertEquals(wuser[2][0], 'someguy')
 
864
        self.assertEquals(wuser[2][1], 'otherguy')
 
865
        self.assertEquals(wuser[2][2], 'otherguy')
 
866
        self.assertEquals(wuser[2][3], 'realmname')
 
867
        self.assertEquals(wuser[2][4], '*')
 
868
        self.assertEquals(wuser[2][5], 'otherguy')
 
869
 
 
870
        self.assertEquals(wserver[0], 'realmname')
 
871
        self.assertEquals(wserver[1], '312')
 
872
        self.assertEquals(wserver[2][0], 'someguy')
 
873
        self.assertEquals(wserver[2][1], 'otherguy')
 
874
        self.assertEquals(wserver[2][2], 'realmname')
 
875
        self.assertEquals(wserver[2][3], 'Hi mom!')
 
876
 
 
877
        self.assertEquals(idle[0], 'realmname')
 
878
        self.assertEquals(idle[1], '317')
 
879
        self.assertEquals(idle[2][0], 'someguy')
 
880
        self.assertEquals(idle[2][1], 'otherguy')
 
881
        self.assertEquals(idle[2][2], '15')
 
882
        self.assertEquals(idle[2][3], '10')
 
883
        self.assertEquals(idle[2][4], "seconds idle, signon time")
 
884
 
 
885
        self.assertEquals(channels[0], 'realmname')
 
886
        self.assertEquals(channels[1], '319')
 
887
        self.assertEquals(channels[2][0], 'someguy')
 
888
        self.assertEquals(channels[2][1], 'otherguy')
 
889
        self.assertEquals(channels[2][2], '#groupA #groupB')
 
890
 
 
891
        self.assertEquals(end[0], 'realmname')
 
892
        self.assertEquals(end[1], '318')
 
893
        self.assertEquals(end[2][0], 'someguy')
 
894
        self.assertEquals(end[2][1], 'otherguy')
 
895
        self.assertEquals(end[2][2], 'End of WHOIS list.')
 
896
    testWhois = dG(testWhois)
 
897
 
 
898
 
 
899
class TestMind(service.PBMind):
 
900
    def __init__(self, *a, **kw):
 
901
        self.joins = []
 
902
        self.parts = []
 
903
        self.messages = []
 
904
        self.meta = []
 
905
 
 
906
    def remote_userJoined(self, user, group):
 
907
        self.joins.append((user, group))
 
908
 
 
909
 
 
910
    def remote_userLeft(self, user, group, reason):
 
911
        self.parts.append((user, group, reason))
 
912
 
 
913
 
 
914
    def remote_receive(self, sender, recipient, message):
 
915
        self.messages.append((sender, recipient, message))
 
916
 
 
917
 
 
918
    def remote_groupMetaUpdate(self, group, meta):
 
919
        self.meta.append((group, meta))
 
920
pb.setUnjellyableForClass(TestMind, service.PBMindReference)
 
921
 
 
922
 
 
923
class PBProtocolTestCase(unittest.TestCase):
 
924
    def setUp(self):
 
925
        self.realm = service.InMemoryWordsRealm("realmname")
 
926
        self.checker = checkers.InMemoryUsernamePasswordDatabaseDontUse()
 
927
        self.portal = portal.Portal(
 
928
            self.realm, [self.checker])
 
929
        self.serverFactory = pb.PBServerFactory(self.portal)
 
930
        self.serverFactory.protocol = self._protocolFactory
 
931
        self.serverFactory.unsafeTracebacks = True
 
932
        self.clientFactory = pb.PBClientFactory()
 
933
        self.clientFactory.unsafeTracebacks = True
 
934
        self.serverPort = reactor.listenTCP(0, self.serverFactory)
 
935
        self.clientConn = reactor.connectTCP(
 
936
            '127.0.0.1',
 
937
            self.serverPort.getHost().port,
 
938
            self.clientFactory)
 
939
 
 
940
 
 
941
    def _protocolFactory(self, *args, **kw):
 
942
        self._serverProtocol = pb.Broker(0)
 
943
        return self._serverProtocol
 
944
 
 
945
 
 
946
    def tearDown(self):
 
947
        d3 = Deferred()
 
948
        self._serverProtocol.notifyOnDisconnect(lambda: d3.callback(None))
 
949
        return DeferredList([
 
950
            maybeDeferred(self.serverPort.stopListening),
 
951
            maybeDeferred(self.clientConn.disconnect), d3])
 
952
 
 
953
 
 
954
    def _loggedInAvatar(self, name, password, mind):
 
955
        creds = credentials.UsernamePassword(name, password)
 
956
        self.checker.addUser(name.encode('ascii'), password)
 
957
        d = self.realm.createUser(name)
 
958
        d.addCallback(lambda ign: self.clientFactory.login(creds, mind))
 
959
        return d
 
960
 
 
961
 
 
962
    def testGroups(self):
 
963
        mindone = TestMind()
 
964
        one = wFD(self._loggedInAvatar(u"one", "p1", mindone))
 
965
        yield one
 
966
        one = one.getResult()
 
967
 
 
968
        mindtwo = TestMind()
 
969
        two = wFD(self._loggedInAvatar(u"two", "p2", mindtwo))
 
970
        yield two
 
971
        two = two.getResult()
 
972
 
 
973
        add = wFD(self.realm.createGroup(u"foobar"))
 
974
        yield add
 
975
        add.getResult()
 
976
 
 
977
        groupone = wFD(one.join(u"foobar"))
 
978
        yield groupone
 
979
        groupone = groupone.getResult()
 
980
 
 
981
        grouptwo = wFD(two.join(u"foobar"))
 
982
        yield grouptwo
 
983
        grouptwo = grouptwo.getResult()
 
984
 
 
985
        msg = wFD(groupone.send({"text": "hello, monkeys"}))
 
986
        yield msg
 
987
        msg = msg.getResult()
 
988
 
 
989
        leave = wFD(groupone.leave())
 
990
        yield leave
 
991
        leave = leave.getResult()
 
992
    testGroups = dG(testGroups)