OLD | NEW |
| (Empty) |
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, succee
d | |
18 from twisted.internet.defer import deferredGenerator as dG, waitForDeferred as w
FD | |
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 T
rue | |
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 Fals
e | |
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', 'fi
rstuser 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_fel
low', '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_fel
low', '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 topi
c.']) | |
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', 'otherus
er', '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 su
ch 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) | |
OLD | NEW |