source:
ralphm-patches/message-stanza.patch
@
75:9b7b8b99da61
Last change on this file since 75:9b7b8b99da61 was 75:9b7b8b99da61, checked in by Ralph Meijer <ralphm@…>, 7 years ago | |
---|---|
File size: 11.0 KB |
-
wokkel/test/test_xmppim.py
# HG changeset patch # Parent 5df04f703f9024cd3a73d51117df93e7f56fdd7a Parse message stanzas into Message objects. This replaces `MessageProtocol.onMessage` with `messageReceived` and `errorReceived`. Incoming messages stanzas are parsed by the `fromElement` class method of the class set in `MessageProtocol.messageFactory`. This defaults to the `Message` class. The resulting object is passed to `messageReceived`. If the message type was `error`, the message is parsed as a `wokkel.generic.ErrorStanza` instead, and passed to `errorReceived`. `Message` now normalizes the message type of empty or unknown values to `normal` per RFC 6120. diff --git a/wokkel/test/test_xmppim.py b/wokkel/test/test_xmppim.py
a b 1336 1336 d = self.handleRequest(xml) 1337 1337 d.addCallback(cb) 1338 1338 return d 1339 1340 1341 1342 class MessageTest(unittest.TestCase): 1343 """ 1344 Tests for L{xmppim.Message}. 1345 """ 1346 1347 def test_defaultStanzaType(self): 1348 """ 1349 The default stanza type is 'normal'. 1350 """ 1351 message = xmppim.Message() 1352 self.assertEqual('normal', message.stanzaType) 1353 1354 1355 def test_fromElementStanzaTypeEmpty(self): 1356 """ 1357 The empty stanza type is parsed as 'normal'. 1358 """ 1359 xml = u"""<message/>""" 1360 message = xmppim.Message.fromElement(parseXml(xml)) 1361 self.assertEqual('normal', message.stanzaType) 1362 1363 1364 def test_fromElementStanzaTypeError(self): 1365 """ 1366 The error stanza type is parsed as 'error'. 1367 """ 1368 xml = u"""<message type='error'/>""" 1369 message = xmppim.Message.fromElement(parseXml(xml)) 1370 self.assertEqual('error', message.stanzaType) 1371 1372 1373 def test_fromElementBody(self): 1374 """ 1375 The message body is parsed into the body attribute. 1376 """ 1377 xml = u""" 1378 <message> 1379 <body>Hello</body> 1380 </message> 1381 """ 1382 message = xmppim.Message.fromElement(parseXml(xml)) 1383 self.assertEqual(u'Hello', message.body) 1384 1385 1386 def test_fromElementSubject(self): 1387 """ 1388 The message subject is parsed into the subject attribute. 1389 """ 1390 xml = u""" 1391 <message> 1392 <subject>Greeting</subject> 1393 </message> 1394 """ 1395 message = xmppim.Message.fromElement(parseXml(xml)) 1396 self.assertEqual(u'Greeting', message.subject) 1397 1398 1399 def test_toElement(self): 1400 message = xmppim.Message(body=u'Hello', subject=u'Greeting') 1401 message.stanzaType = u'chat' 1402 1403 element = message.toElement() 1404 1405 self.assertEqual(u'chat', element.getAttribute(u'type')) 1406 self.assertEqual(u'Hello', unicode(element.body)) 1407 self.assertEqual(u'Greeting', unicode(element.subject)) 1408 1409 1410 1411 class MessageProtocolTest(unittest.TestCase): 1412 """ 1413 Tests for L{xmppim.MessageProtocol}. 1414 """ 1415 1416 def setUp(self): 1417 self.stub = XmlStreamStub() 1418 self.protocol = xmppim.MessageProtocol() 1419 self.protocol.makeConnection(self.stub.xmlstream) 1420 self.protocol.connectionInitialized() 1421 1422 1423 def test_messageReceived(self): 1424 """ 1425 Message stanzas are observed. 1426 """ 1427 received = [] 1428 self.patch(self.protocol, 'messageReceived', received.append) 1429 1430 xml = """ 1431 <message to='example.org'> 1432 <body>Hello</body> 1433 </message> 1434 """ 1435 1436 message = parseXml(xml) 1437 self.stub.send(message) 1438 1439 self.assertEqual(1, len(received)) 1440 stanza = received[-1] 1441 self.assertEqual(u'Hello', stanza.body) 1442 1443 1444 def test_errorReceived(self): 1445 """ 1446 Message stanzas of type error are received by errorReceived. 1447 """ 1448 messagesReceived = [] 1449 errorsReceived = [] 1450 self.patch(self.protocol, 'messageReceived', messagesReceived.append) 1451 self.patch(self.protocol, 'errorReceived', errorsReceived.append) 1452 1453 xml = """ 1454 <message to='example.org' type='error'> 1455 <error type='cancel'> 1456 <service-unavailable 1457 xmlns='urn:ietf:params:xml:ns:xmpp-stanzas'/> 1458 </error> 1459 </message> 1460 """ 1461 1462 message = parseXml(xml) 1463 self.stub.send(message) 1464 1465 self.assertEqual(0, len(messagesReceived)) 1466 self.assertEqual(1, len(errorsReceived)) 1467 stanza = errorsReceived[-1] 1468 self.assertEqual(u'service-unavailable', stanza.exception.condition) 1469 1470 1471 def test_messageHandled(self): 1472 """ 1473 Message stanzas marked as handled are ignored. 1474 """ 1475 received = [] 1476 self.patch(self.protocol, 'messageReceived', received.append) 1477 1478 xml = """ 1479 <message to='example.org'> 1480 <body>Hello</body> 1481 </message> 1482 """ 1483 1484 message = parseXml(xml) 1485 message.handled = True 1486 self.stub.send(message) 1487 1488 self.assertEqual(0, len(received)) 1489 1490 1491 def test_onMessage(self): 1492 """ 1493 The deprecated onMessage is called if present. 1494 """ 1495 received = [] 1496 self.protocol.onMessage = received.append 1497 1498 xml = """ 1499 <message to='example.org'> 1500 <body>Hello</body> 1501 </message> 1502 """ 1503 1504 message = parseXml(xml) 1505 self.stub.send(message) 1506 1507 self.assertEqual(1, len(received)) 1508 element = received[-1] 1509 self.assertEqual(u'message', element.name) 1510 self.assertEqual(u'normal', element['type']) 1511 1512 warnings = self.flushWarnings() 1513 self.assertEqual(1, len(warnings)) 1514 1515 self.assertEqual("wokkel.xmppim.MessageProtocol.onMessage " 1516 "was deprecated in Wokkel 0.8.0; " 1517 "please use MessageProtocol.messageReceived instead.", 1518 warnings[0]['message']) 1519 1520 1521 def test_onMessageError(self): 1522 """ 1523 The deprecated onMessage is not called for error messages. 1524 """ 1525 received = [] 1526 self.protocol.onMessage = received.append 1527 1528 xml = """ 1529 <message to='example.org' type='error'> 1530 <error type='cancel'> 1531 <service-unavailable 1532 xmlns='urn:ietf:params:xml:ns:xmpp-stanzas'/> 1533 </error> 1534 </message> 1535 """ 1536 1537 message = parseXml(xml) 1538 self.stub.send(message) 1539 1540 self.assertEqual(0, len(received)) 1541 1542 warnings = self.flushWarnings() 1543 self.assertEqual(1, len(warnings)) 1544 1545 self.assertEqual("wokkel.xmppim.MessageProtocol.onMessage " 1546 "was deprecated in Wokkel 0.8.0; " 1547 "please use MessageProtocol.messageReceived instead.", 1548 warnings[0]['message']) -
wokkel/xmppim.py
diff --git a/wokkel/xmppim.py b/wokkel/xmppim.py
a b 20 20 from wokkel.generic import ErrorStanza, Stanza, Request 21 21 from wokkel.subprotocols import IQHandlerMixin 22 22 from wokkel.subprotocols import XMPPHandler 23 from wokkel.subprotocols import asyncObserver 23 24 24 25 NS_XML = 'http://www.w3.org/XML/1998/namespace' 25 26 NS_ROSTER = 'jabber:iq:roster' … … 1006 1007 A message stanza. 1007 1008 """ 1008 1009 1009 stanzaKind = 'message' 1010 stanzaKind = u'message' 1011 stanzaType = u'normal' 1012 _messageTypes = u'normal', u'chat', u'headline', u'groupchat', u'error' 1010 1013 1011 1014 childParsers = { 1012 (None, 'body'): '_childParser_body',1013 (None, 'subject'): '_childParser_subject',1015 (None, u'body'): '_childParser_body', 1016 (None, u'subject'): '_childParser_subject', 1014 1017 } 1015 1018 1016 1019 def __init__(self, recipient=None, sender=None, body=None, subject=None): … … 1031 1034 element = Stanza.toElement(self) 1032 1035 1033 1036 if self.body: 1034 element.addElement( 'body', content=self.body)1037 element.addElement(u'body', content=self.body) 1035 1038 if self.subject: 1036 element.addElement( 'subject', content=self.subject)1039 element.addElement(u'subject', content=self.subject) 1037 1040 1038 1041 return element 1039 1042 1040 1043 1044 @classmethod 1045 def fromElement(cls, element): 1046 stanza = super(Message, cls).fromElement(element) 1047 if stanza.stanzaType not in cls._messageTypes: 1048 stanza.stanzaType = u'normal' 1049 return stanza 1050 1051 1041 1052 1042 1053 class MessageProtocol(XMPPHandler): 1043 1054 """ 1044 1055 Generic XMPP subprotocol handler for incoming message stanzas. 1056 1057 @cvar messageFactory: The class to parse messages into. Its C{fromElement} 1058 will be called with the received L{domish.Element}. Defaults to 1059 L{Message}. 1045 1060 """ 1046 1061 1047 message Types = None, 'normal', 'chat', 'headline', 'groupchat'1062 messageFactory = Message 1048 1063 1049 1064 def connectionInitialized(self): 1050 1065 self.xmlstream.addObserver("/message", self._onMessage) 1051 1066 1052 def _onMessage(self, message):1053 if message.handled:1054 return1055 1067 1056 messageType = message.getAttribute("type") 1068 @asyncObserver 1069 def _onMessage(self, element): 1070 if element.getAttribute(u'type') == u'error': 1071 stanza = ErrorStanza.fromElement(element) 1072 return self.errorReceived(stanza) 1073 else: 1074 stanza = self.messageFactory.fromElement(element) 1075 return self.messageReceived(stanza) 1057 1076 1058 if messageType == 'error':1059 return1060 1077 1061 if messageType not in self.messageTypes: 1062 message["type"] = 'normal' 1078 def errorReceived(self, stanza): 1079 """ 1080 Called when a message stanza of type error was received. 1063 1081 1064 self.onMessage(message) 1082 @type stanza: L{ErrorStanza} 1083 """ 1084 if hasattr(self, 'onMessage'): 1085 warnings.warn( 1086 "wokkel.xmppim.MessageProtocol.onMessage " 1087 "was deprecated in Wokkel 0.8.0; " 1088 "please use MessageProtocol.messageReceived instead.", 1089 DeprecationWarning) 1090 return False 1065 1091 1066 def onMessage(self, message): 1092 1093 def messageReceived(self, message): 1067 1094 """ 1068 1095 Called when a message stanza was received. 1096 1097 Override this method to handle a message. To let other handlers 1098 process this message, return C{False} (synchronously). 1099 1100 The caller of this method uses L{asyncObserver}, so that 1101 deferreds can also be returned and exceptions are handled properly. 1102 1103 @rtype: L{bool} or L{Deferred} 1069 1104 """ 1105 if hasattr(self, 'onMessage'): 1106 warnings.warn( 1107 "wokkel.xmppim.MessageProtocol.onMessage " 1108 "was deprecated in Wokkel 0.8.0; " 1109 "please use MessageProtocol.messageReceived instead.", 1110 DeprecationWarning) 1111 1112 if message.stanzaType == u'normal': 1113 # Override stanza type for backwards compatibility. 1114 message.element[u'type'] = u'normal' 1115 1116 self.onMessage(message.element) 1117 return getattr(message, "handled", False)
Note: See TracBrowser
for help on using the repository browser.