| 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 |