Changeset 5:231bc3e8b810 in ralphm-patches
- Timestamp:
- Apr 1, 2009, 2:17:03 PM (13 years ago)
- Branch:
- default
- Files:
-
- 4 edited
Legend:
- Unmodified
- Added
- Removed
-
compat-pre-twisted-8.0.0.patch
r1 r5 1 diff -r 9c14d48c54b2 wokkel/compat.py 2 --- a/wokkel/compat.py Wed Feb 04 14:41:26 2009 +0100 3 +++ b/wokkel/compat.py Wed Feb 04 14:42:14 2009 +0100 4 @@ -6,40 +6,6 @@ 5 from twisted.internet import protocol 1 diff -r 6fa0283e522b wokkel/compat.py 2 --- a/wokkel/compat.py Wed Mar 25 18:14:08 2009 +0100 3 +++ b/wokkel/compat.py Wed Mar 25 18:15:15 2009 +0100 4 @@ -7,40 +7,6 @@ 6 5 from twisted.words.protocols.jabber import xmlstream 7 6 from twisted.words.xish import domish 8 - 7 9 8 -def toResponse(stanza, stanzaType=None): 10 9 - """ … … 40 39 - 41 40 - 42 41 - 43 42 class BootstrapMixin(object): 44 43 """ 45 diff -r 9c14d48c54b2 wokkel/subprotocols.py 46 --- a/wokkel/subprotocols.py Wed Feb 04 14:41:26 2009 +0100 47 +++ b/wokkel/subprotocols.py Wed Feb 04 14:42:14 2009 +0100 44 XmlStream factory mixin to install bootstrap event observers. 45 diff -r 6fa0283e522b wokkel/subprotocols.py 46 --- a/wokkel/subprotocols.py Wed Mar 25 18:14:08 2009 +0100 47 +++ b/wokkel/subprotocols.py Wed Mar 25 18:15:15 2009 +0100 48 48 @@ -1,6 +1,6 @@ 49 49 # -*- test-case-name: wokkel.test.test_subprotocols -*- … … 54 54 55 55 """ 56 @@ -12,1 3 +12,9@@56 @@ -12,14 +12,10 @@ 57 57 from twisted.internet import defer 58 58 from twisted.python import log … … 61 61 from twisted.words.xish import xpath 62 62 from twisted.words.xish.domish import IElement 63 - 63 64 64 -try: 65 65 - from twisted.words.protocols.jabber.xmlstream import toResponse 66 66 -except ImportError: 67 67 - from wokkel.compat import toResponse 68 68 - 69 69 from wokkel.iwokkel import IXMPPHandler, IXMPPHandlerCollection 70 70 71 diff -r 9c14d48c54b2 wokkel/test/test_compat.py 72 --- a/wokkel/test/test_compat.py Wed Feb 04 14:41:26 2009 +0100 73 +++ b/wokkel/test/test_compat.py Wed Feb 04 14:42:14 2009 +0100 71 class XMPPHandler(object): 72 diff -r 6fa0283e522b wokkel/test/test_compat.py 73 --- a/wokkel/test/test_compat.py Wed Mar 25 18:14:08 2009 +0100 74 +++ b/wokkel/test/test_compat.py Wed Mar 25 18:15:15 2009 +0100 74 75 @@ -1,5 +1,5 @@ 75 76 -# Copyright (c) 2001-2007 Twisted Matrix Laboratories. … … 89 90 class DummyProtocol(protocol.Protocol, utility.EventDispatcher): 90 91 """ 91 @@ -77,75 +77,6 @@ 92 93 dispatcher.dispatch(None, '//event/myevent') 94 self.assertFalse(called) 95 - 96 - 97 - 92 @@ -80,75 +80,6 @@ 93 94 95 98 96 -class ToResponseTest(unittest.TestCase): 99 97 - … … 162 160 - response = toResponse(stanza) 163 161 - self.failIf(response.hasAttribute('type')) 164 165 166 167 diff -r 9c14d48c54b2 wokkel/test/test_disco.py 168 --- a/wokkel/test/test_disco.py Wed Feb 04 14:41:26 2009 +0100 169 +++ b/wokkel/test/test_disco.py Wed Feb 04 14:42:14 2009 +0100 170 @@ -10,17 +10,13 @@ 162 - 163 - 164 - 165 class XmlStreamServerFactoryTest(BootstrapMixinTest): 166 """ 167 Tests for L{XmlStreamServerFactory}. 168 diff -r 6fa0283e522b wokkel/test/test_disco.py 169 --- a/wokkel/test/test_disco.py Wed Mar 25 18:14:08 2009 +0100 170 +++ b/wokkel/test/test_disco.py Wed Mar 25 18:15:15 2009 +0100 171 @@ -10,6 +10,7 @@ 171 172 from twisted.internet import defer 172 173 from twisted.trial import unittest … … 176 177 177 178 from wokkel import data_form, disco 178 from wokkel.generic import parseXml 179 @@ -17,11 +18,6 @@ 179 180 from wokkel.subprotocols import XMPPHandler 180 181 from wokkel.test.helpers import TestableRequestHandlerMixin, XmlStreamStub 181 - 182 182 183 -try: 183 184 - from twisted.words.protocols.jabber.xmlstream import toResponse 184 185 -except ImportError: 185 186 - from wokkel.compat import toResponse 186 187 - 187 188 NS_DISCO_INFO = 'http://jabber.org/protocol/disco#info' 188 189 NS_DISCO_ITEMS = 'http://jabber.org/protocol/disco#items' 189 diff -r 9c14d48c54b2 wokkel/test/test_pubsub.py 190 --- a/wokkel/test/test_pubsub.py Wed Feb 04 14:41:26 2009 +0100 191 +++ b/wokkel/test/test_pubsub.py Wed Feb 04 14:42:14 2009 +0100 190 191 diff -r 6fa0283e522b wokkel/test/test_pubsub.py 192 --- a/wokkel/test/test_pubsub.py Wed Mar 25 18:14:08 2009 +0100 193 +++ b/wokkel/test/test_pubsub.py Wed Mar 25 18:15:15 2009 +0100 192 194 @@ -1,4 +1,4 @@ 193 195 -# Copyright (c) 2003-2008 Ralph Meijer … … 196 198 197 199 """ 198 @@ -12,1 4 +12,10@@200 @@ -12,16 +12,12 @@ 199 201 from twisted.words.xish import domish 200 202 from twisted.words.protocols.jabber import error … … 202 204 +from twisted.words.protocols.jabber.xmlstream import toResponse 203 205 204 from wokkel import data_form, iwokkel, pubsub, shim 206 from wokkel import data_form, disco, iwokkel, pubsub, shim 207 from wokkel.generic import parseXml 205 208 from wokkel.test.helpers import TestableRequestHandlerMixin, XmlStreamStub 206 - 209 207 210 -try: 208 211 - from twisted.words.protocols.jabber.xmlstream import toResponse 209 212 -except ImportError: 210 213 - from wokkel.compat import toResponse 211 214 - 212 215 NS_PUBSUB = 'http://jabber.org/protocol/pubsub' 213 216 NS_PUBSUB_CONFIG = 'http://jabber.org/protocol/pubsub#node_config' 217 NS_PUBSUB_ERRORS = 'http://jabber.org/protocol/pubsub#errors' -
pubsub_client_sender.patch
r4 r5 1 diff -r 8be0600d2c32wokkel/pubsub.py2 --- a/wokkel/pubsub.py Mon Mar 23 09:00:162009 +01003 +++ b/wokkel/pubsub.py Mon Mar 23 09:00:242009 +01001 diff -r 5a91781194ab wokkel/pubsub.py 2 --- a/wokkel/pubsub.py Mon Mar 23 21:43:25 2009 +0100 3 +++ b/wokkel/pubsub.py Mon Mar 23 21:50:36 2009 +0100 4 4 @@ -605,7 +605,7 @@ 5 5 pass … … 92 92 def cb(iq): 93 93 items = [] 94 diff -r 8be0600d2c32wokkel/test/test_pubsub.py95 --- a/wokkel/test/test_pubsub.py Mon Mar 23 09:00:162009 +010096 +++ b/wokkel/test/test_pubsub.py Mon Mar 23 09:00:242009 +010097 @@ -25 7,6 +257,22 @@94 diff -r 5a91781194ab wokkel/test/test_pubsub.py 95 --- a/wokkel/test/test_pubsub.py Mon Mar 23 21:43:25 2009 +0100 96 +++ b/wokkel/test/test_pubsub.py Mon Mar 23 21:50:36 2009 +0100 97 @@ -258,6 +258,22 @@ 98 98 return d 99 99 … … 118 118 """ 119 119 Test sending delete request. 120 @@ -28 0,6 +296,22 @@120 @@ -281,6 +297,22 @@ 121 121 return d 122 122 … … 141 141 """ 142 142 Test sending publish request. 143 @@ -33 1,6 +363,23 @@143 @@ -332,6 +364,23 @@ 144 144 return d 145 145 … … 165 165 """ 166 166 Test sending subscription request. 167 @@ -40 0,6 +449,27 @@167 @@ -401,6 +450,27 @@ 168 168 return d 169 169 … … 193 193 """ 194 194 Test sending unsubscription request. 195 @@ -42 3,6 +493,20 @@195 @@ -424,6 +494,20 @@ 196 196 return d 197 197 … … 214 214 """ 215 215 Test sending items request. 216 @@ -4 89,6 +573,25 @@216 @@ -490,6 +574,25 @@ 217 217 return d 218 218 … … 238 238 + 239 239 240 class PubSub ServiceTest(unittest.TestCase, TestableRequestHandlerMixin):241 """240 class PubSubRequestTest(unittest.TestCase): 241 -
pubsub_request.patch
r4 r5 11 11 that is passed to the corresponding handler methods. 12 12 13 diff -r 884ac8d88411wokkel/generic.py14 --- a/wokkel/generic.py T hu Mar 05 16:29:122009 +010015 +++ b/wokkel/generic.py Wed Mar 18 09:26:202009 +010013 diff -r bcbcbc4aa868 wokkel/generic.py 14 --- a/wokkel/generic.py Tue Mar 24 09:25:36 2009 +0100 15 +++ b/wokkel/generic.py Wed Mar 25 18:13:56 2009 +0100 16 16 @@ -10,7 +10,7 @@ 17 17 from zope.interface import implements … … 58 58 + self.recipient = jid.internJID(element['to']) 59 59 + self.stanzaType = element.getAttribute('type') 60 diff -r 884ac8d88411wokkel/iwokkel.py61 --- a/wokkel/iwokkel.py T hu Mar 05 16:29:122009 +010062 +++ b/wokkel/iwokkel.py Wed Mar 18 09:26:202009 +010060 diff -r bcbcbc4aa868 wokkel/iwokkel.py 61 --- a/wokkel/iwokkel.py Tue Mar 24 09:25:36 2009 +0100 62 +++ b/wokkel/iwokkel.py Wed Mar 25 18:13:56 2009 +0100 63 63 @@ -278,6 +278,7 @@ 64 64 C{list} of L{domish.Element}) … … 340 340 + @rtype: L{defer.Deferred} 341 341 """ 342 diff -r 884ac8d88411wokkel/pubsub.py343 --- a/wokkel/pubsub.py T hu Mar 05 16:29:122009 +0100344 +++ b/wokkel/pubsub.py Wed Mar 18 09:26:202009 +0100342 diff -r bcbcbc4aa868 wokkel/pubsub.py 343 --- a/wokkel/pubsub.py Tue Mar 24 09:25:36 2009 +0100 344 +++ b/wokkel/pubsub.py Wed Mar 25 18:13:56 2009 +0100 345 345 @@ -16,7 +16,7 @@ 346 346 from twisted.words.protocols.jabber import jid, error, xmlstream … … 352 352 from wokkel.iwokkel import IPubSubClient, IPubSubService 353 353 354 @@ -32,42 +32,10 @@ 354 @@ -31,43 +31,12 @@ 355 NS_PUBSUB_OWNER = NS_PUBSUB + "#owner" 355 356 NS_PUBSUB_NODE_CONFIG = NS_PUBSUB + "#node_config" 356 357 NS_PUBSUB_META_DATA = NS_PUBSUB + "#meta-data" 358 +NS_PUBSUB_SUBSCRIBE_OPTIONS = NS_PUBSUB + "#subscribe_options" 357 359 358 360 -# In publish-subscribe namespace XPath query selector. … … 399 401 class SubscriptionPending(Exception): 400 402 """ 401 @@ -167,40 +135,350 @@ 403 @@ -98,12 +67,18 @@ 404 405 406 407 -class BadRequest(PubSubError): 408 +class BadRequest(error.StanzaError): 409 """ 410 Bad request stanza error. 411 """ 412 def __init__(self, pubsubCondition=None, text=None): 413 - PubSubError.__init__(self, 'bad-request', pubsubCondition, text) 414 + if pubsubCondition: 415 + appCondition = domish.Element((NS_PUBSUB_ERRORS, pubsubCondition)) 416 + else: 417 + appCondition = None 418 + error.StanzaError.__init__(self, 'bad-request', 419 + text=text, 420 + appCondition=appCondition) 421 422 423 424 @@ -167,40 +142,362 @@ 402 425 403 426 … … 500 523 + 'subscribe': ['nodeOrEmpty', 'jid'], 501 524 + 'unsubscribe': ['nodeOrEmpty', 'jid'], 502 + 'optionsGet': [ ],503 + 'optionsSet': [ ],525 + 'optionsGet': ['nodeOrEmpty', 'jid'], 526 + 'optionsSet': ['nodeOrEmpty', 'jid', 'options'], 504 527 + 'subscriptions': [], 505 528 + 'affiliations': [], … … 662 685 + self.options = {} 663 686 + else: 664 + raise BadRequest( "Unexpected form type %r" % form.formType)687 + raise BadRequest(text="Unexpected form type %r" % form.formType) 665 688 + else: 666 + raise BadRequest( "Missing configuration form")689 + raise BadRequest(text="Missing configuration form") 667 690 + 668 691 + … … 712 735 + verbElement['max_items'] = unicode(self.maxItems) 713 736 + 737 + 738 + def _parse_options(self, verbElement): 739 + form = PubSubRequest._findForm(verbElement, NS_PUBSUB_SUBSCRIBE_OPTIONS) 740 + if form: 741 + if form.formType == 'submit': 742 + self.options = form.getValues() 743 + elif form.formType == 'cancel': 744 + self.options = {} 745 + else: 746 + raise BadRequest(text="Unexpected form type %r" % form.formType) 747 + else: 748 + raise BadRequest(text="Missing options form") 714 749 + 715 750 + def parseElement(self, element): … … 773 808 774 809 775 @@ -336,11 +6 14,9 @@810 @@ -336,11 +633,9 @@ 776 811 @param nodeIdentifier: Optional suggestion for the id of the node. 777 812 @type nodeIdentifier: C{unicode} … … 788 823 def cb(iq): 789 824 try: 790 @@ -350,7 +6 26,9 @@825 @@ -350,7 +645,9 @@ 791 826 new_node = nodeIdentifier 792 827 return new_node … … 799 834 800 835 def deleteNode(self, service, nodeIdentifier): 801 @@ -362,9 +6 40,10 @@836 @@ -362,9 +659,10 @@ 802 837 @param nodeIdentifier: The identifier of the node. 803 838 @type nodeIdentifier: C{unicode} … … 813 848 814 849 def subscribe(self, service, nodeIdentifier, subscriber): 815 @@ -379,10 +6 58,10 @@850 @@ -379,10 +677,10 @@ 816 851 will get notifications of new published items. 817 852 @type subscriber: L{JID} … … 828 863 def cb(iq): 829 864 subscription = iq.pubsub.subscription["subscription"] 830 @@ -397,7 +6 76,9 @@865 @@ -397,7 +695,9 @@ 831 866 # yielded a stanza error. 832 867 return None … … 839 874 840 875 def unsubscribe(self, service, nodeIdentifier, subscriber): 841 @@ -411,11 + 692,11 @@876 @@ -411,11 +711,11 @@ 842 877 @param subscriber: The entity to unsubscribe from the node. 843 878 @type subscriber: L{JID} … … 856 891 857 892 def publish(self, service, nodeIdentifier, items=None): 858 @@ -429,13 +7 10,11 @@893 @@ -429,13 +729,11 @@ 859 894 @param items: Optional list of L{Item}s to publish. 860 895 @type items: C{list} … … 875 910 876 911 def items(self, service, nodeIdentifier, maxItems=None): 877 @@ -449,11 +7 28,11 @@912 @@ -449,11 +747,11 @@ 878 913 @param maxItems: Optional limit on the number of retrieved items. 879 914 @type maxItems: C{int} … … 891 926 def cb(iq): 892 927 items = [] 893 @@ -462,7 +7 41,9 @@928 @@ -462,7 +760,9 @@ 894 929 items.append(element) 895 930 return items … … 902 937 903 938 904 @@ -497,27 +7 78,7 @@939 @@ -497,27 +797,7 @@ 905 940 implements(IPubSubService) 906 941 … … 931 966 932 967 933 @@ -530,10 + 791,7 @@968 @@ -530,10 +810,7 @@ 934 969 935 970 … … 943 978 944 979 def getDiscoInfo(self, requestor, target, nodeIdentifier): 945 @@ -585,92 +8 43,17 @@980 @@ -585,92 +862,17 @@ 946 981 return d 947 982 … … 1043 1078 def toResponse(result): 1044 1079 response = domish.Element((NS_PUBSUB, "pubsub")) 1045 @@ -681,28 +8 64,24 @@1080 @@ -681,28 +883,24 @@ 1046 1081 subscription["subscription"] = result.state 1047 1082 return response … … 1078 1113 def toResponse(result): 1079 1114 response = domish.Element((NS_PUBSUB, 'pubsub')) 1080 @@ -714,13 + 893,12 @@1115 @@ -714,13 +912,12 @@ 1081 1116 item['subscription'] = subscription.state 1082 1117 return response … … 1094 1129 def toResponse(result): 1095 1130 response = domish.Element((NS_PUBSUB, 'pubsub')) 1096 @@ -733,17 +9 11,15 @@1131 @@ -733,17 +930,15 @@ 1097 1132 1098 1133 return response … … 1115 1150 create = response.addElement('create') 1116 1151 create['node'] = result 1117 @@ -751,7 +9 27,7 @@1152 @@ -751,7 +946,7 @@ 1118 1153 else: 1119 1154 return None … … 1124 1159 return d 1125 1160 1126 @@ -771,6 +9 47,7 @@1161 @@ -771,6 +966,7 @@ 1127 1162 fields.append(data_form.Field.fromDict(option)) 1128 1163 return fields … … 1132 1167 options = self.getConfigurationOptions() 1133 1168 fields = self._makeFields(options, values) 1134 @@ -780,6 +9 57,7 @@1169 @@ -780,6 +976,7 @@ 1135 1170 1136 1171 return form … … 1140 1175 options = self.getConfigurationOptions() 1141 1176 processedValues = {} 1142 @@ -805,8 + 983,7 @@1177 @@ -805,8 +1002,7 @@ 1143 1178 return processedValues 1144 1179 … … 1150 1185 def toResponse(options): 1151 1186 response = domish.Element((NS_PUBSUB_OWNER, "pubsub")) 1152 @@ -814,127 + 991,82 @@1187 @@ -814,127 +1010,82 @@ 1153 1188 default.addChild(self._formFromConfiguration(options).toElement()) 1154 1189 return response … … 1305 1340 1306 1341 # public methods 1307 @@ -990,27 +11 22,27 @@1342 @@ -990,27 +1141,27 @@ 1308 1343 return [] 1309 1344 … … 1339 1374 1340 1375 1341 @@ -1018,30 +11 50,29 @@1376 @@ -1018,30 +1169,29 @@ 1342 1377 return {} 1343 1378 … … 1377 1412 + def delete(self, request): 1378 1413 raise Unsupported('delete-nodes') 1379 diff -r 884ac8d88411 wokkel/test/test_pubsub.py 1380 --- a/wokkel/test/test_pubsub.py Thu Mar 05 16:29:12 2009 +0100 1381 +++ b/wokkel/test/test_pubsub.py Wed Mar 18 09:26:20 2009 +0100 1382 @@ -507,6 +507,29 @@ 1414 diff -r bcbcbc4aa868 wokkel/test/test_pubsub.py 1415 --- a/wokkel/test/test_pubsub.py Tue Mar 24 09:25:36 2009 +0100 1416 +++ b/wokkel/test/test_pubsub.py Wed Mar 25 18:13:56 2009 +0100 1417 @@ -14,6 +14,7 @@ 1418 from twisted.words.protocols.jabber.jid import JID 1419 1420 from wokkel import data_form, iwokkel, pubsub, shim 1421 +from wokkel.generic import parseXml 1422 from wokkel.test.helpers import TestableRequestHandlerMixin, XmlStreamStub 1423 1424 try: 1425 @@ -490,6 +491,630 @@ 1426 1427 1428 1429 +class PubSubRequestTest(unittest.TestCase): 1430 + 1431 + def test_fromElementPublish(self): 1432 + """ 1433 + Test parsing a publish request. 1434 + """ 1435 + 1436 + xml = """ 1437 + <iq type='set' to='pubsub.example.org' 1438 + from='user@example.org'> 1439 + <pubsub xmlns='http://jabber.org/protocol/pubsub'> 1440 + <publish node='test'/> 1441 + </pubsub> 1442 + </iq> 1443 + """ 1444 + 1445 + request = pubsub.PubSubRequest.fromElement(parseXml(xml)) 1446 + self.assertEqual('publish', request.verb) 1447 + self.assertEqual(JID('user@example.org'), request.sender) 1448 + self.assertEqual(JID('pubsub.example.org'), request.recipient) 1449 + self.assertEqual('test', request.nodeIdentifier) 1450 + self.assertEqual([], request.items) 1451 + 1452 + 1453 + def test_fromElementPublishItems(self): 1454 + """ 1455 + Test parsing a publish request with items. 1456 + """ 1457 + 1458 + xml = """ 1459 + <iq type='set' to='pubsub.example.org' 1460 + from='user@example.org'> 1461 + <pubsub xmlns='http://jabber.org/protocol/pubsub'> 1462 + <publish node='test'> 1463 + <item id="item1"/> 1464 + <item id="item2"/> 1465 + </publish> 1466 + </pubsub> 1467 + </iq> 1468 + """ 1469 + 1470 + request = pubsub.PubSubRequest.fromElement(parseXml(xml)) 1471 + self.assertEqual(2, len(request.items)) 1472 + self.assertEqual(u'item1', request.items[0]["id"]) 1473 + self.assertEqual(u'item2', request.items[1]["id"]) 1474 + 1475 + 1476 + def test_fromElementPublishNoNode(self): 1477 + """ 1478 + A publish request to the root node should raise an exception. 1479 + """ 1480 + xml = """ 1481 + <iq type='set' to='pubsub.example.org' 1482 + from='user@example.org'> 1483 + <pubsub xmlns='http://jabber.org/protocol/pubsub'> 1484 + <publish/> 1485 + </pubsub> 1486 + </iq> 1487 + """ 1488 + 1489 + err = self.assertRaises(error.StanzaError, 1490 + pubsub.PubSubRequest.fromElement, 1491 + parseXml(xml)) 1492 + self.assertEqual('bad-request', err.condition) 1493 + self.assertEqual(NS_PUBSUB_ERRORS, err.appCondition.uri) 1494 + self.assertEqual('nodeid-required', err.appCondition.name) 1495 + 1496 + 1497 + def test_fromElementSubscribe(self): 1498 + """ 1499 + Test parsing a subscription request. 1500 + """ 1501 + 1502 + xml = """ 1503 + <iq type='set' to='pubsub.example.org' 1504 + from='user@example.org'> 1505 + <pubsub xmlns='http://jabber.org/protocol/pubsub'> 1506 + <subscribe node='test' jid='user@example.org/Home'/> 1507 + </pubsub> 1508 + </iq> 1509 + """ 1510 + 1511 + request = pubsub.PubSubRequest.fromElement(parseXml(xml)) 1512 + self.assertEqual('subscribe', request.verb) 1513 + self.assertEqual(JID('user@example.org'), request.sender) 1514 + self.assertEqual(JID('pubsub.example.org'), request.recipient) 1515 + self.assertEqual('test', request.nodeIdentifier) 1516 + self.assertEqual(JID('user@example.org/Home'), request.subscriber) 1517 + 1518 + 1519 + def test_fromElementSubscribeEmptyNode(self): 1520 + """ 1521 + Test parsing a subscription request to the root node. 1522 + """ 1523 + 1524 + xml = """ 1525 + <iq type='set' to='pubsub.example.org' 1526 + from='user@example.org'> 1527 + <pubsub xmlns='http://jabber.org/protocol/pubsub'> 1528 + <subscribe jid='user@example.org/Home'/> 1529 + </pubsub> 1530 + </iq> 1531 + """ 1532 + 1533 + request = pubsub.PubSubRequest.fromElement(parseXml(xml)) 1534 + self.assertEqual('', request.nodeIdentifier) 1535 + 1536 + 1537 + def test_fromElementSubscribeNoJID(self): 1538 + """ 1539 + Subscribe requests without a JID should raise a bad-request exception. 1540 + """ 1541 + xml = """ 1542 + <iq type='set' to='pubsub.example.org' 1543 + from='user@example.org'> 1544 + <pubsub xmlns='http://jabber.org/protocol/pubsub'> 1545 + <subscribe node='test'/> 1546 + </pubsub> 1547 + </iq> 1548 + """ 1549 + err = self.assertRaises(error.StanzaError, 1550 + pubsub.PubSubRequest.fromElement, 1551 + parseXml(xml)) 1552 + self.assertEqual('bad-request', err.condition) 1553 + self.assertEqual(NS_PUBSUB_ERRORS, err.appCondition.uri) 1554 + self.assertEqual('jid-required', err.appCondition.name) 1555 + 1556 + def test_fromElementUnsubscribe(self): 1557 + """ 1558 + Test parsing an unsubscription request. 1559 + """ 1560 + 1561 + xml = """ 1562 + <iq type='set' to='pubsub.example.org' 1563 + from='user@example.org'> 1564 + <pubsub xmlns='http://jabber.org/protocol/pubsub'> 1565 + <unsubscribe node='test' jid='user@example.org/Home'/> 1566 + </pubsub> 1567 + </iq> 1568 + """ 1569 + 1570 + request = pubsub.PubSubRequest.fromElement(parseXml(xml)) 1571 + self.assertEqual('unsubscribe', request.verb) 1572 + self.assertEqual(JID('user@example.org'), request.sender) 1573 + self.assertEqual(JID('pubsub.example.org'), request.recipient) 1574 + self.assertEqual('test', request.nodeIdentifier) 1575 + self.assertEqual(JID('user@example.org/Home'), request.subscriber) 1576 + 1577 + 1578 + def test_fromElementUnsubscribeNoJID(self): 1579 + """ 1580 + Unsubscribe requests without a JID should raise a bad-request exception. 1581 + """ 1582 + xml = """ 1583 + <iq type='set' to='pubsub.example.org' 1584 + from='user@example.org'> 1585 + <pubsub xmlns='http://jabber.org/protocol/pubsub'> 1586 + <unsubscribe node='test'/> 1587 + </pubsub> 1588 + </iq> 1589 + """ 1590 + err = self.assertRaises(error.StanzaError, 1591 + pubsub.PubSubRequest.fromElement, 1592 + parseXml(xml)) 1593 + self.assertEqual('bad-request', err.condition) 1594 + self.assertEqual(NS_PUBSUB_ERRORS, err.appCondition.uri) 1595 + self.assertEqual('jid-required', err.appCondition.name) 1596 + 1597 + 1598 + def test_fromElementOptionsGet(self): 1599 + """ 1600 + Test parsing a request for getting subscription options. 1601 + """ 1602 + 1603 + xml = """ 1604 + <iq type='get' to='pubsub.example.org' 1605 + from='user@example.org'> 1606 + <pubsub xmlns='http://jabber.org/protocol/pubsub'> 1607 + <options node='test' jid='user@example.org/Home'/> 1608 + </pubsub> 1609 + </iq> 1610 + """ 1611 + 1612 + request = pubsub.PubSubRequest.fromElement(parseXml(xml)) 1613 + self.assertEqual('optionsGet', request.verb) 1614 + 1615 + 1616 + def test_fromElementOptionsSet(self): 1617 + """ 1618 + Test parsing a request for setting subscription options. 1619 + """ 1620 + 1621 + xml = """ 1622 + <iq type='set' to='pubsub.example.org' 1623 + from='user@example.org'> 1624 + <pubsub xmlns='http://jabber.org/protocol/pubsub'> 1625 + <options node='test' jid='user@example.org/Home'> 1626 + <x xmlns='jabber:x:data' type='submit'> 1627 + <field var='FORM_TYPE' type='hidden'> 1628 + <value>http://jabber.org/protocol/pubsub#subscribe_options</value> 1629 + </field> 1630 + <field var='pubsub#deliver'><value>1</value></field> 1631 + </x> 1632 + </options> 1633 + </pubsub> 1634 + </iq> 1635 + """ 1636 + 1637 + request = pubsub.PubSubRequest.fromElement(parseXml(xml)) 1638 + self.assertEqual('optionsSet', request.verb) 1639 + self.assertEqual(JID('user@example.org'), request.sender) 1640 + self.assertEqual(JID('pubsub.example.org'), request.recipient) 1641 + self.assertEqual('test', request.nodeIdentifier) 1642 + self.assertEqual(JID('user@example.org/Home'), request.subscriber) 1643 + self.assertEqual({'pubsub#deliver': '1'}, request.options) 1644 + 1645 + 1646 + def test_fromElementOptionsSetCancel(self): 1647 + """ 1648 + Test parsing a request for cancelling setting subscription options. 1649 + """ 1650 + 1651 + xml = """ 1652 + <iq type='set' to='pubsub.example.org' 1653 + from='user@example.org'> 1654 + <pubsub xmlns='http://jabber.org/protocol/pubsub'> 1655 + <options node='test' jid='user@example.org/Home'> 1656 + <x xmlns='jabber:x:data' type='cancel'/> 1657 + </options> 1658 + </pubsub> 1659 + </iq> 1660 + """ 1661 + 1662 + request = pubsub.PubSubRequest.fromElement(parseXml(xml)) 1663 + self.assertEqual({}, request.options) 1664 + 1665 + 1666 + def test_fromElementOptionsSetBadFormType(self): 1667 + """ 1668 + On a options set request unknown fields should be ignored. 1669 + """ 1670 + 1671 + xml = """ 1672 + <iq type='set' to='pubsub.example.org' 1673 + from='user@example.org'> 1674 + <pubsub xmlns='http://jabber.org/protocol/pubsub'> 1675 + <options node='test' jid='user@example.org/Home'> 1676 + <x xmlns='jabber:x:data' type='result'> 1677 + <field var='FORM_TYPE' type='hidden'> 1678 + <value>http://jabber.org/protocol/pubsub#node_config</value> 1679 + </field> 1680 + <field var='pubsub#deliver'><value>1</value></field> 1681 + </x> 1682 + </options> 1683 + </pubsub> 1684 + </iq> 1685 + """ 1686 + 1687 + err = self.assertRaises(error.StanzaError, 1688 + pubsub.PubSubRequest.fromElement, 1689 + parseXml(xml)) 1690 + self.assertEqual('bad-request', err.condition) 1691 + self.assertEqual(None, err.appCondition) 1692 + 1693 + 1694 + def test_fromElementOptionsSetNoForm(self): 1695 + """ 1696 + On a options set request a form is required. 1697 + """ 1698 + 1699 + xml = """ 1700 + <iq type='set' to='pubsub.example.org' 1701 + from='user@example.org'> 1702 + <pubsub xmlns='http://jabber.org/protocol/pubsub'> 1703 + <options node='test' jid='user@example.org/Home'/> 1704 + </pubsub> 1705 + </iq> 1706 + """ 1707 + err = self.assertRaises(error.StanzaError, 1708 + pubsub.PubSubRequest.fromElement, 1709 + parseXml(xml)) 1710 + self.assertEqual('bad-request', err.condition) 1711 + self.assertEqual(None, err.appCondition) 1712 + 1713 + 1714 + def test_fromElementSubscriptions(self): 1715 + """ 1716 + Test parsing a request for all subscriptions. 1717 + """ 1718 + 1719 + xml = """ 1720 + <iq type='get' to='pubsub.example.org' 1721 + from='user@example.org'> 1722 + <pubsub xmlns='http://jabber.org/protocol/pubsub'> 1723 + <subscriptions/> 1724 + </pubsub> 1725 + </iq> 1726 + """ 1727 + 1728 + request = pubsub.PubSubRequest.fromElement(parseXml(xml)) 1729 + self.assertEqual('subscriptions', request.verb) 1730 + self.assertEqual(JID('user@example.org'), request.sender) 1731 + self.assertEqual(JID('pubsub.example.org'), request.recipient) 1732 + 1733 + 1734 + def test_fromElementAffiliations(self): 1735 + """ 1736 + Test parsing a request for all affiliations. 1737 + """ 1738 + 1739 + xml = """ 1740 + <iq type='get' to='pubsub.example.org' 1741 + from='user@example.org'> 1742 + <pubsub xmlns='http://jabber.org/protocol/pubsub'> 1743 + <affiliations/> 1744 + </pubsub> 1745 + </iq> 1746 + """ 1747 + 1748 + request = pubsub.PubSubRequest.fromElement(parseXml(xml)) 1749 + self.assertEqual('affiliations', request.verb) 1750 + self.assertEqual(JID('user@example.org'), request.sender) 1751 + self.assertEqual(JID('pubsub.example.org'), request.recipient) 1752 + 1753 + 1754 + def test_fromElementCreate(self): 1755 + """ 1756 + Test parsing a request to create a node. 1757 + """ 1758 + 1759 + xml = """ 1760 + <iq type='set' to='pubsub.example.org' 1761 + from='user@example.org'> 1762 + <pubsub xmlns='http://jabber.org/protocol/pubsub'> 1763 + <create node='mynode'/> 1764 + </pubsub> 1765 + </iq> 1766 + """ 1767 + 1768 + request = pubsub.PubSubRequest.fromElement(parseXml(xml)) 1769 + self.assertEqual('create', request.verb) 1770 + self.assertEqual(JID('user@example.org'), request.sender) 1771 + self.assertEqual(JID('pubsub.example.org'), request.recipient) 1772 + self.assertEqual('mynode', request.nodeIdentifier) 1773 + 1774 + 1775 + def test_fromElementCreateInstant(self): 1776 + """ 1777 + Test parsing a request to create an instant node. 1778 + """ 1779 + 1780 + xml = """ 1781 + <iq type='set' to='pubsub.example.org' 1782 + from='user@example.org'> 1783 + <pubsub xmlns='http://jabber.org/protocol/pubsub'> 1784 + <create/> 1785 + </pubsub> 1786 + </iq> 1787 + """ 1788 + 1789 + request = pubsub.PubSubRequest.fromElement(parseXml(xml)) 1790 + self.assertIdentical(None, request.nodeIdentifier) 1791 + 1792 + 1793 + def test_fromElementDefault(self): 1794 + """ 1795 + Test parsing a request for the default node configuration. 1796 + """ 1797 + 1798 + xml = """ 1799 + <iq type='get' to='pubsub.example.org' 1800 + from='user@example.org'> 1801 + <pubsub xmlns='http://jabber.org/protocol/pubsub#owner'> 1802 + <default/> 1803 + </pubsub> 1804 + </iq> 1805 + """ 1806 + 1807 + request = pubsub.PubSubRequest.fromElement(parseXml(xml)) 1808 + self.assertEqual('default', request.verb) 1809 + self.assertEqual(JID('user@example.org'), request.sender) 1810 + self.assertEqual(JID('pubsub.example.org'), request.recipient) 1811 + self.assertEqual('leaf', request.nodeType) 1812 + 1813 + 1814 + def test_fromElementDefaultCollection(self): 1815 + """ 1816 + Parsing a request for the default configuration extracts the node type. 1817 + """ 1818 + 1819 + xml = """ 1820 + <iq type='get' to='pubsub.example.org' 1821 + from='user@example.org'> 1822 + <pubsub xmlns='http://jabber.org/protocol/pubsub#owner'> 1823 + <default> 1824 + <x xmlns='jabber:x:data' type='submit'> 1825 + <field var='FORM_TYPE' type='hidden'> 1826 + <value>http://jabber.org/protocol/pubsub#node_config</value> 1827 + </field> 1828 + <field var='pubsub#node_type'> 1829 + <value>collection</value> 1830 + </field> 1831 + </x> 1832 + </default> 1833 + 1834 + </pubsub> 1835 + </iq> 1836 + """ 1837 + 1838 + request = pubsub.PubSubRequest.fromElement(parseXml(xml)) 1839 + self.assertEqual('collection', request.nodeType) 1840 + 1841 + 1842 + def test_fromElementConfigureGet(self): 1843 + """ 1844 + Test parsing a node configuration get request. 1845 + """ 1846 + 1847 + xml = """ 1848 + <iq type='get' to='pubsub.example.org' 1849 + from='user@example.org'> 1850 + <pubsub xmlns='http://jabber.org/protocol/pubsub#owner'> 1851 + <configure node='test'/> 1852 + </pubsub> 1853 + </iq> 1854 + """ 1855 + 1856 + request = pubsub.PubSubRequest.fromElement(parseXml(xml)) 1857 + self.assertEqual('configureGet', request.verb) 1858 + self.assertEqual(JID('user@example.org'), request.sender) 1859 + self.assertEqual(JID('pubsub.example.org'), request.recipient) 1860 + self.assertEqual('test', request.nodeIdentifier) 1861 + 1862 + 1863 + def test_fromElementConfigureSet(self): 1864 + """ 1865 + On a node configuration set request the Data Form is parsed. 1866 + """ 1867 + 1868 + xml = """ 1869 + <iq type='set' to='pubsub.example.org' 1870 + from='user@example.org'> 1871 + <pubsub xmlns='http://jabber.org/protocol/pubsub#owner'> 1872 + <configure node='test'> 1873 + <x xmlns='jabber:x:data' type='submit'> 1874 + <field var='FORM_TYPE' type='hidden'> 1875 + <value>http://jabber.org/protocol/pubsub#node_config</value> 1876 + </field> 1877 + <field var='pubsub#deliver_payloads'><value>0</value></field> 1878 + <field var='pubsub#persist_items'><value>1</value></field> 1879 + </x> 1880 + </configure> 1881 + </pubsub> 1882 + </iq> 1883 + """ 1884 + 1885 + request = pubsub.PubSubRequest.fromElement(parseXml(xml)) 1886 + self.assertEqual('configureSet', request.verb) 1887 + self.assertEqual(JID('user@example.org'), request.sender) 1888 + self.assertEqual(JID('pubsub.example.org'), request.recipient) 1889 + self.assertEqual('test', request.nodeIdentifier) 1890 + self.assertEqual({'pubsub#deliver_payloads': '0', 1891 + 'pubsub#persist_items': '1'}, request.options) 1892 + 1893 + 1894 + def test_fromElementConfigureSetCancel(self): 1895 + """ 1896 + The node configuration is cancelled, so no options. 1897 + """ 1898 + 1899 + xml = """ 1900 + <iq type='set' to='pubsub.example.org' 1901 + from='user@example.org'> 1902 + <pubsub xmlns='http://jabber.org/protocol/pubsub#owner'> 1903 + <configure node='test'> 1904 + <x xmlns='jabber:x:data' type='cancel'/> 1905 + </configure> 1906 + </pubsub> 1907 + </iq> 1908 + """ 1909 + 1910 + request = pubsub.PubSubRequest.fromElement(parseXml(xml)) 1911 + self.assertEqual({}, request.options) 1912 + 1913 + 1914 + def test_fromElementConfigureSetBadFormType(self): 1915 + """ 1916 + On a node configuration set request unknown fields should be ignored. 1917 + """ 1918 + 1919 + xml = """ 1920 + <iq type='set' to='pubsub.example.org' 1921 + from='user@example.org'> 1922 + <pubsub xmlns='http://jabber.org/protocol/pubsub#owner'> 1923 + <configure node='test'> 1924 + <x xmlns='jabber:x:data' type='result'> 1925 + <field var='FORM_TYPE' type='hidden'> 1926 + <value>http://jabber.org/protocol/pubsub#node_config</value> 1927 + </field> 1928 + <field var='pubsub#deliver_payloads'><value>0</value></field> 1929 + <field var='x-myfield'><value>1</value></field> 1930 + </x> 1931 + </configure> 1932 + </pubsub> 1933 + </iq> 1934 + """ 1935 + 1936 + err = self.assertRaises(error.StanzaError, 1937 + pubsub.PubSubRequest.fromElement, 1938 + parseXml(xml)) 1939 + self.assertEqual('bad-request', err.condition) 1940 + self.assertEqual(None, err.appCondition) 1941 + 1942 + 1943 + def test_fromElementConfigureSetNoForm(self): 1944 + """ 1945 + On a node configuration set request a form is required. 1946 + """ 1947 + 1948 + xml = """ 1949 + <iq type='set' to='pubsub.example.org' 1950 + from='user@example.org'> 1951 + <pubsub xmlns='http://jabber.org/protocol/pubsub#owner'> 1952 + <configure node='test'/> 1953 + </pubsub> 1954 + </iq> 1955 + """ 1956 + err = self.assertRaises(error.StanzaError, 1957 + pubsub.PubSubRequest.fromElement, 1958 + parseXml(xml)) 1959 + self.assertEqual('bad-request', err.condition) 1960 + self.assertEqual(None, err.appCondition) 1961 + 1962 + 1963 + def test_fromElementItems(self): 1964 + """ 1965 + Test parsing an items request. 1966 + """ 1967 + xml = """ 1968 + <iq type='get' to='pubsub.example.org' 1969 + from='user@example.org'> 1970 + <pubsub xmlns='http://jabber.org/protocol/pubsub'> 1971 + <items node='test'/> 1972 + </pubsub> 1973 + </iq> 1974 + """ 1975 + 1976 + request = pubsub.PubSubRequest.fromElement(parseXml(xml)) 1977 + self.assertEqual('items', request.verb) 1978 + self.assertEqual(JID('user@example.org'), request.sender) 1979 + self.assertEqual(JID('pubsub.example.org'), request.recipient) 1980 + self.assertEqual('test', request.nodeIdentifier) 1981 + self.assertIdentical(None, request.maxItems) 1982 + self.assertEqual([], request.itemIdentifiers) 1983 + 1984 + 1985 + def test_fromElementRetract(self): 1986 + """ 1987 + Test parsing a retract request. 1988 + """ 1989 + 1990 + xml = """ 1991 + <iq type='set' to='pubsub.example.org' 1992 + from='user@example.org'> 1993 + <pubsub xmlns='http://jabber.org/protocol/pubsub'> 1994 + <retract node='test'> 1995 + <item id='item1'/> 1996 + <item id='item2'/> 1997 + </retract> 1998 + </pubsub> 1999 + </iq> 2000 + """ 2001 + 2002 + request = pubsub.PubSubRequest.fromElement(parseXml(xml)) 2003 + self.assertEqual('retract', request.verb) 2004 + self.assertEqual(JID('user@example.org'), request.sender) 2005 + self.assertEqual(JID('pubsub.example.org'), request.recipient) 2006 + self.assertEqual('test', request.nodeIdentifier) 2007 + self.assertEqual(['item1', 'item2'], request.itemIdentifiers) 2008 + 2009 + 2010 + def test_fromElementPurge(self): 2011 + """ 2012 + Test parsing a purge request. 2013 + """ 2014 + 2015 + xml = """ 2016 + <iq type='set' to='pubsub.example.org' 2017 + from='user@example.org'> 2018 + <pubsub xmlns='http://jabber.org/protocol/pubsub#owner'> 2019 + <purge node='test'/> 2020 + </pubsub> 2021 + </iq> 2022 + """ 2023 + 2024 + request = pubsub.PubSubRequest.fromElement(parseXml(xml)) 2025 + self.assertEqual('purge', request.verb) 2026 + self.assertEqual(JID('user@example.org'), request.sender) 2027 + self.assertEqual(JID('pubsub.example.org'), request.recipient) 2028 + self.assertEqual('test', request.nodeIdentifier) 2029 + 2030 + 2031 + def test_fromElementDelete(self): 2032 + """ 2033 + Test parsing a delete request. 2034 + """ 2035 + 2036 + xml = """ 2037 + <iq type='set' to='pubsub.example.org' 2038 + from='user@example.org'> 2039 + <pubsub xmlns='http://jabber.org/protocol/pubsub#owner'> 2040 + <delete node='test'/> 2041 + </pubsub> 2042 + </iq> 2043 + """ 2044 + 2045 + request = pubsub.PubSubRequest.fromElement(parseXml(xml)) 2046 + self.assertEqual('delete', request.verb) 2047 + self.assertEqual(JID('user@example.org'), request.sender) 2048 + self.assertEqual(JID('pubsub.example.org'), request.recipient) 2049 + self.assertEqual('test', request.nodeIdentifier) 2050 + 2051 + 2052 + 2053 class PubSubServiceTest(unittest.TestCase, TestableRequestHandlerMixin): 2054 """ 2055 Tests for L{pubsub.PubSubService}. 2056 @@ -507,6 +1132,29 @@ 1383 2057 verify.verifyObject(iwokkel.IPubSubService, self.service) 1384 2058 … … 1410 2084 """ 1411 2085 Test getDiscoInfo calls getNodeInfo and returns some minimal info. 1412 @@ -561,20 +584,149 @@ 2086 @@ -524,28 +1172,6 @@ 2087 return d 2088 2089 2090 - def test_onPublishNoNode(self): 2091 - """ 2092 - The root node is always a collection, publishing is a bad request. 2093 - """ 2094 - xml = """ 2095 - <iq type='set' to='pubsub.example.org' 2096 - from='user@example.org'> 2097 - <pubsub xmlns='http://jabber.org/protocol/pubsub'> 2098 - <publish/> 2099 - </pubsub> 2100 - </iq> 2101 - """ 2102 - 2103 - def cb(result): 2104 - self.assertEquals('bad-request', result.condition) 2105 - 2106 - d = self.handleRequest(xml) 2107 - self.assertFailure(d, error.StanzaError) 2108 - d.addCallback(cb) 2109 - return d 2110 - 2111 - 2112 def test_onPublish(self): 2113 """ 2114 A publish request should result in L{PubSubService.publish} being 2115 @@ -561,27 +1187,147 @@ 1413 2116 </iq> 1414 2117 """ … … 1420 2123 - self.assertEqual([], items) 1421 2124 + def publish(request): 1422 + self.assertEqual(JID('user@example.org'), request.sender)1423 + self.assertEqual(JID('pubsub.example.org'), request.recipient)1424 + self.assertEqual('test', request.nodeIdentifier)1425 + self.assertEqual([], request.items)1426 2125 return defer.succeed(None) 1427 2126 … … 1431 2130 1432 2131 1433 + def test_onPublishItems(self):1434 + """1435 + A publish request with items should pass the items onto C{publish}.1436 + """1437 +1438 + xml = """1439 + <iq type='set' to='pubsub.example.org'1440 + from='user@example.org'>1441 + <pubsub xmlns='http://jabber.org/protocol/pubsub'>1442 + <publish node='test'>1443 + <item id="item1"/>1444 + <item id="item2"/>1445 + </publish>1446 + </pubsub>1447 + </iq>1448 + """1449 +1450 + def publish(request):1451 + self.assertEqual(2, len(request.items))1452 + self.assertEqual(u'item1', request.items[0]["id"])1453 + self.assertEqual(u'item2', request.items[1]["id"])1454 + return defer.succeed(None)1455 +1456 + self.service.publish = publish1457 + verify.verifyObject(iwokkel.IPubSubService, self.service)1458 + return self.handleRequest(xml)1459 +1460 +1461 2132 + def test_onSubscribe(self): 1462 2133 + """ … … 1474 2145 + 1475 2146 + def subscribe(request): 1476 + self.assertEqual(JID('user@example.org'), request.sender)1477 + self.assertEqual(JID('pubsub.example.org'), request.recipient)1478 + self.assertEqual('test', request.nodeIdentifier)1479 + self.assertEqual(JID('user@example.org/Home'), request.subscriber)1480 2147 + return defer.succeed(pubsub.Subscription(request.nodeIdentifier, 1481 2148 + request.subscriber, … … 1513 2180 + 1514 2181 + def subscribe(request): 1515 + self.assertEqual('', request.nodeIdentifier)1516 2182 + return defer.succeed(pubsub.Subscription(request.nodeIdentifier, 1517 2183 + request.subscriber, … … 1543 2209 + 1544 2210 + def unsubscribe(request): 1545 + self.assertEqual(JID('user@example.org'), request.sender)1546 + self.assertEqual(JID('pubsub.example.org'), request.recipient)1547 + self.assertEqual('test', request.nodeIdentifier)1548 + self.assertEqual(JID('user@example.org/Home'), request.subscriber)1549 2211 + return defer.succeed(None) 1550 2212 + … … 1566 2228 1567 2229 xml = """ 1568 @@ -597,6 +749,31 @@ 1569 return d 1570 1571 1572 + def test_onOptionsSet(self): 1573 + """ 1574 + Setting subscription options is not supported. 1575 + """ 1576 + 1577 + xml = """ 1578 + <iq type='set' to='pubsub.example.org' 1579 + from='user@example.org'> 1580 + <pubsub xmlns='http://jabber.org/protocol/pubsub'> 1581 + <options/> 2230 <iq type='get' to='pubsub.example.org' 2231 from='user@example.org'> 2232 <pubsub xmlns='http://jabber.org/protocol/pubsub'> 2233 - <options/> 2234 + <options node='test' jid='user@example.org/Home'/> 1582 2235 + </pubsub> 1583 2236 + </iq> … … 1595 2248 + 1596 2249 + 1597 def test_onSubscriptions(self): 1598 """ 1599 A subscriptions request should result in 1600 @@ -627,14 +804,149 @@ 2250 + def test_onOptionsSet(self): 2251 + """ 2252 + Setting subscription options is not supported. 2253 + """ 2254 + 2255 + xml = """ 2256 + <iq type='set' to='pubsub.example.org' 2257 + from='user@example.org'> 2258 + <pubsub xmlns='http://jabber.org/protocol/pubsub'> 2259 + <options node='test' jid='user@example.org/Home'> 2260 + <x xmlns='jabber:x:data' type='submit'> 2261 + <field var='FORM_TYPE' type='hidden'> 2262 + <value>http://jabber.org/protocol/pubsub#subscribe_options</value> 2263 + </field> 2264 + <field var='pubsub#deliver'><value>1</value></field> 2265 + </x> 2266 + </options> 2267 </pubsub> 2268 </iq> 2269 """ 2270 @@ -627,14 +1373,141 @@ 1601 2271 self.assertEqual('subscribed', subscription['subscription']) 1602 2272 … … 1606 2276 - self.assertEqual(JID('pubsub.example.org'), service) 1607 2277 + def subscriptions(request): 1608 + self.assertEqual(JID('user@example.org'), request.sender)1609 + self.assertEqual(JID('pubsub.example.org'), request.recipient)1610 2278 subscription = pubsub.Subscription('test', JID('user@example.org'), 1611 2279 'subscribed') … … 1649 2317 + 1650 2318 + def affiliations(request): 1651 + self.assertEqual(JID('user@example.org'), request.sender)1652 + self.assertEqual(JID('pubsub.example.org'), request.recipient)1653 2319 + affiliation = ('test', 'owner') 1654 2320 + return defer.succeed([affiliation]) … … 1676 2342 + 1677 2343 + def create(request): 1678 + self.assertEqual(JID('user@example.org'), request.sender)1679 + self.assertEqual(JID('pubsub.example.org'), request.recipient)1680 + self.assertEqual('mynode', request.nodeIdentifier)1681 2344 + return defer.succeed(request.nodeIdentifier) 1682 2345 + … … 1737 2400 + 1738 2401 + def create(request): 1739 + self.assertIdentical(None, request.nodeIdentifier)1740 2402 + return defer.succeed(u'random') 1741 2403 + … … 1751 2413 d.addCallback(cb) 1752 2414 return d 1753 @@ -665,10 + 977,10@@2415 @@ -665,10 +1538,7 @@ 1754 2416 "label": "Deliver payloads with event notifications"} 1755 2417 } … … 1760 2422 - self.assertEqual('leaf', nodeType) 1761 2423 + def getDefaultConfiguration(request): 1762 + self.assertEqual(JID('user@example.org'), request.sender)1763 + self.assertEqual(JID('pubsub.example.org'), request.recipient)1764 + self.assertEqual('leaf', request.nodeType)1765 2424 return defer.succeed({}) 1766 2425 1767 2426 def cb(element): 1768 @@ -686,6 + 998,95 @@2427 @@ -686,6 +1556,85 @@ 1769 2428 return d 1770 2429 … … 1802 2461 + 1803 2462 + def getDefaultConfiguration(request): 1804 + self.assertEqual('collection', request.nodeType)1805 2463 + return defer.succeed({}) 1806 +1807 + def cb(element):1808 + self.assertEqual('pubsub', element.name)1809 + self.assertEqual(NS_PUBSUB_OWNER, element.uri)1810 + self.assertEqual(NS_PUBSUB_OWNER, element.default.uri)1811 + form = data_form.Form.fromElement(element.default.x)1812 + self.assertEqual(NS_PUBSUB_CONFIG, form.formNamespace)1813 2464 + 1814 2465 + self.service.getConfigurationOptions = getConfigurationOptions 1815 2466 + self.service.getDefaultConfiguration = getDefaultConfiguration 1816 2467 + verify.verifyObject(iwokkel.IPubSubService, self.service) 1817 + d = self.handleRequest(xml) 1818 + d.addCallback(cb) 1819 + return d 2468 + return self.handleRequest(xml) 1820 2469 + 1821 2470 + … … 1862 2511 """ 1863 2512 On a node configuration get request L{PubSubService.getConfiguration} 1864 @@ -714,14 +1 115,15@@2513 @@ -714,14 +1663,11 @@ 1865 2514 "label": "Owner of the node"} 1866 2515 } … … 1870 2519 - self.assertEqual(JID('pubsub.example.org'), service) 1871 2520 - self.assertEqual('test', nodeIdentifier) 2521 - 1872 2522 + def getConfiguration(request): 1873 + self.assertEqual(JID('user@example.org'), request.sender)1874 + self.assertEqual(JID('pubsub.example.org'), request.recipient)1875 + self.assertEqual('test', request.nodeIdentifier)1876 1877 2523 return defer.succeed({'pubsub#deliver_payloads': '0', 1878 2524 'pubsub#persist_items': '1', … … 1883 2529 def cb(element): 1884 2530 self.assertEqual('pubsub', element.name) 1885 @@ -749,8 +1 151,12 @@2531 @@ -749,8 +1695,12 @@ 1886 2532 field.typeCheck() 1887 2533 self.assertEqual(JID('user@example.org'), field.value) … … 1896 2542 d.addCallback(cb) 1897 2543 return d 1898 @@ -789,16 +1 195,17@@2544 @@ -789,16 +1739,14 @@ 1899 2545 "label": "Deliver payloads with event notifications"} 1900 2546 } … … 1905 2551 - self.assertEqual('test', nodeIdentifier) 1906 2552 + def setConfiguration(request): 1907 + self.assertEqual(JID('user@example.org'), request.sender)1908 + self.assertEqual(JID('pubsub.example.org'), request.recipient)1909 + self.assertEqual('test', request.nodeIdentifier)1910 2553 self.assertEqual({'pubsub#deliver_payloads': False, 1911 2554 - 'pubsub#persist_items': True}, options) … … 1919 2562 1920 2563 1921 @@ -823,10 +1 230,11 @@2564 @@ -823,10 +1771,11 @@ 1922 2565 </iq> 1923 2566 """ … … 1932 2575 1933 2576 1934 @@ -862,14 +1 270,47 @@2577 @@ -862,14 +1811,47 @@ 1935 2578 "label": "Deliver payloads with event notifications"} 1936 2579 } … … 1982 2625 """ 1983 2626 On a items request, return all items for the given node. 1984 @@ -883,12 +1 324,12@@2627 @@ -883,12 +1865,7 @@ 1985 2628 </iq> 1986 2629 """ … … 1993 2636 - self.assertEqual([], items) 1994 2637 + def items(request): 1995 + self.assertEqual(JID('user@example.org'), request.sender)1996 + self.assertEqual(JID('pubsub.example.org'), request.recipient)1997 + self.assertEqual('test', request.nodeIdentifier)1998 + self.assertIdentical(None, request.maxItems)1999 + self.assertEqual([], request.itemIdentifiers)2000 2638 return defer.succeed([pubsub.Item('current')]) 2001 2639 2002 2640 def cb(element): 2003 @@ -925,11 +1 366,11@@2641 @@ -925,11 +1902,7 @@ 2004 2642 </iq> 2005 2643 """ … … 2011 2649 - self.assertEqual(['item1', 'item2'], itemIdentifiers) 2012 2650 + def retract(request): 2013 + self.assertEqual(JID('user@example.org'), request.sender)2014 + self.assertEqual(JID('pubsub.example.org'), request.recipient)2015 + self.assertEqual('test', request.nodeIdentifier)2016 + self.assertEqual(['item1', 'item2'], request.itemIdentifiers)2017 2651 return defer.succeed(None) 2018 2652 2019 2653 self.service.retract = retract 2020 @@ -951,10 +1 392,10@@2654 @@ -951,10 +1924,7 @@ 2021 2655 </iq> 2022 2656 """ … … 2027 2661 - self.assertEqual('test', nodeIdentifier) 2028 2662 + def purge(request): 2029 + self.assertEqual(JID('user@example.org'), request.sender)2030 + self.assertEqual(JID('pubsub.example.org'), request.recipient)2031 + self.assertEqual('test', request.nodeIdentifier)2032 2663 return defer.succeed(None) 2033 2664 2034 2665 self.service.purge = purge 2035 @@ -976,10 +1 417,10@@2666 @@ -976,10 +1946,7 @@ 2036 2667 </iq> 2037 2668 """ … … 2042 2673 - self.assertEqual('test', nodeIdentifier) 2043 2674 + def delete(request): 2044 + self.assertEqual(JID('user@example.org'), request.sender)2045 + self.assertEqual(JID('pubsub.example.org'), request.recipient)2046 + self.assertEqual('test', request.nodeIdentifier)2047 2675 return defer.succeed(None) 2048 2676 2049 2677 self.service.delete = delete 2050 @@ -1031,3 +1 472,461 @@2678 @@ -1031,3 +1998,461 @@ 2051 2679 self.assertEqual(NS_PUBSUB_EVENT, message.event.delete.redirect.uri) 2052 2680 self.assertTrue(message.event.delete.redirect.hasAttribute('uri')) -
pubsub_resource.patch
r4 r5 1 diff -r dc8ed1ff55d7wokkel/iwokkel.py2 --- a/wokkel/iwokkel.py Wed Mar 18 09:26:242009 +01003 +++ b/wokkel/iwokkel.py Wed Mar 18 20:51:58 2009 +01004 @@ -297,7 6 +297,14@@1 diff -r 2ea6196efcdc wokkel/iwokkel.py 2 --- a/wokkel/iwokkel.py Wed Mar 25 18:14:07 2009 +0100 3 +++ b/wokkel/iwokkel.py Mon Mar 30 08:35:05 2009 +0200 4 @@ -297,75 +297,46 @@ 5 5 """ 6 6 … … 17 17 @type request: L{wokkel.pubsub.PubSubRequest} 18 18 - @return: deferred that fires on success. 19 - @rtype: L{defer.Deferred} 20 - """ 21 - 22 - 19 + """ 20 + 21 + 22 + def getInfo(requestor, service, nodeIdentifier): 23 + """ 24 + Get node type and meta data. 25 + 26 + @param requestor: The entity the request originated from. 27 + @type requestor: L{jid.JID} 28 + @param service: The publish-subscribe service entity. 29 + @type service: L{jid.JID} 30 + @param nodeIdentifier: Identifier of the node to request the info for. 31 + @type nodeIdentifier: L{unicode} 32 + @return: A deferred that fires with a dictionary. If not empty, 33 + it must have the keys C{'type'} and C{'meta-data'} to keep 34 + respectively the node type and a dictionary with the meta 35 + data for that node. 36 @rtype: L{defer.Deferred} 37 """ 38 39 23 40 - def subscribe(request): 24 - """ 41 + def getNodes(requestor, service, nodeIdentifier): 42 """ 25 43 - Called when a subscribe request has been received. 26 - 44 + Get all nodes contained by this node. 45 27 46 - @param request: The publish-subscribe request. 28 47 - @type request: L{wokkel.pubsub.PubSubRequest} … … 79 98 - @return: A deferred that fires with a C{unicode} that represents 80 99 - the identifier of the new node. 81 - @rtype: L{defer.Deferred} 82 """ 83 84 85 @@ -406,7 +344,80 @@ 100 + @param requestor: The entity the request originated from. 101 + @type requestor: L{jid.JID} 102 + @param service: The publish-subscribe service entity. 103 + @type service: L{jid.JID} 104 + @param nodeIdentifier: Identifier of the node to request the childs for. 105 + @type nodeIdentifier: L{unicode} 106 + @return: A deferred that fires with a list of child node identifiers. 107 @rtype: L{defer.Deferred} 108 """ 109 110 @@ -406,7 +377,80 @@ 86 111 """ 87 112 88 113 89 114 - def getDefaultConfiguration(request): 90 + def pub sub_publish(request):115 + def publish(request): 91 116 + """ 92 117 + Called when a publish request has been received. … … 99 124 + 100 125 + 101 + def pubsub_subscribe(request):126 + def subscribe(request): 102 127 + """ 103 128 + Called when a subscribe request has been received. … … 111 136 + 112 137 + 113 + def pubsub_unsubscribe(request):138 + def unsubscribe(request): 114 139 + """ 115 140 + Called when a subscribe request has been received. … … 123 148 + 124 149 + 125 + def pubsub_subscriptions(request):150 + def subscriptions(request): 126 151 + """ 127 152 + Called when a subscriptions retrieval request has been received. … … 135 160 + 136 161 + 137 + def pubsub_affiliations(request):162 + def affiliations(request): 138 163 + """ 139 164 + Called when a affiliations retrieval request has been received. … … 149 174 + 150 175 + 151 + def pubsub_create(request):176 + def create(request): 152 177 + """ 153 178 + Called when a node creation request has been received. … … 161 186 + 162 187 + 163 + def pubsub_default(request):188 + def default(request): 164 189 """ 165 190 Called when a default node configuration request has been received. 166 191 167 @@ -420,7 +4 31,7 @@192 @@ -420,7 +464,7 @@ 168 193 """ 169 194 170 195 171 196 - def getConfiguration(request): 172 + def pubsub_configureGet(request):197 + def configureGet(request): 173 198 """ 174 199 Called when a node configuration retrieval request has been received. 175 200 176 @@ -433,7 +4 44,7 @@201 @@ -433,7 +477,7 @@ 177 202 """ 178 203 179 204 180 205 - def setConfiguration(request): 181 + def pubsub_configureSet(request):206 + def configureSet(request): 182 207 """ 183 208 Called when a node configuration change request has been received. 184 209 185 @@ -445,7 +456,7 @@ 186 """ 187 188 189 - def items(request): 190 + def pubsub_items(request): 191 """ 192 Called when a items retrieval request has been received. 193 194 @@ -456,7 +467,7 @@ 195 """ 196 197 198 - def retract(request): 199 + def pubsub_retract(request): 200 """ 201 Called when a item retraction request has been received. 202 203 @@ -468,7 +479,7 @@ 204 """ 205 206 207 - def purge(request): 208 + def pubsub_purge(request): 209 """ 210 Called when a node purge request has been received. 211 212 @@ -480,7 +491,7 @@ 213 """ 214 215 216 - def delete(request): 217 + def pubsub_delete(request): 218 """ 219 Called when a node deletion request has been received. 220 221 diff -r dc8ed1ff55d7 wokkel/pubsub.py 222 --- a/wokkel/pubsub.py Wed Mar 18 09:26:24 2009 +0100 223 +++ b/wokkel/pubsub.py Wed Mar 18 20:51:58 2009 +0100 224 @@ -18,7 +18,7 @@ 210 diff -r 2ea6196efcdc wokkel/pubsub.py 211 --- a/wokkel/pubsub.py Wed Mar 25 18:14:07 2009 +0100 212 +++ b/wokkel/pubsub.py Mon Mar 30 08:35:05 2009 +0200 213 @@ -13,12 +13,13 @@ 214 from zope.interface import implements 215 216 from twisted.internet import defer 217 +from twisted.python import log 218 from twisted.words.protocols.jabber import jid, error, xmlstream 219 from twisted.words.xish import domish 225 220 226 221 from wokkel import disco, data_form, generic, shim … … 231 226 # Iq get and set XPath queries 232 227 IQ_GET = '/iq[@type="get"]' 233 @@ - 77,11 +77,16 @@228 @@ -84,11 +85,16 @@ 234 229 235 230 class Unsupported(PubSubError): … … 248 243 249 244 class Subscription(object): 250 @@ -2 28,9 +233,9 @@245 @@ -235,9 +241,9 @@ 251 246 'retract': ['node', 'itemIdentifiers'], 252 247 'purge': ['node'], … … 260 255 } 261 256 262 @@ -359,6 +364,9 @@ 263 else: 264 self.nodeType = 'leaf' 265 266 + if self.nodeType not in ('leaf', 'collection'): 267 + raise error.StanzaError('not-acceptable') 268 + 269 270 def _parse_configure(self, verbElement): 271 """ 272 @@ -787,8 +795,8 @@ 257 @@ -806,13 +812,10 @@ 273 258 '/*': '_onPubSubRequest', 274 259 } 275 260 276 - 261 + hideNodes = False 262 277 263 - def __init__(self): 264 - self.discoIdentity = {'category': 'pubsub', 265 - 'type': 'generic', 266 - 'name': 'Generic Publish-Subscribe Service'} 267 - 268 - self.pubSubFeatures = [] 278 269 + def __init__(self, resource): 279 270 + self.resource = resource 280 self.discoIdentity = {'category': 'pubsub', 281 'type': 'generic', 282 'name': 'Generic Publish-Subscribe Service'} 283 @@ -851,91 +859,80 @@ 271 272 273 def connectionMade(self): 274 @@ -820,19 +823,9 @@ 275 276 277 def getDiscoInfo(self, requestor, target, nodeIdentifier): 278 - info = [] 279 - 280 - if not nodeIdentifier: 281 - category, idType, name = self.discoIdentity 282 - info.append(disco.DiscoIdentity(category, idType, name)) 283 - 284 - info.append(disco.DiscoFeature(disco.NS_DISCO_ITEMS)) 285 - info.extend([disco.DiscoFeature("%s#%s" % (NS_PUBSUB, feature)) 286 - for feature in self.pubSubFeatures]) 287 - 288 - def toInfo(nodeInfo): 289 + def toInfo(nodeInfo, info): 290 if not nodeInfo: 291 - return 292 + return info 293 294 (nodeType, metaData) = nodeInfo['type'], nodeInfo['meta-data'] 295 info.append(disco.DiscoIdentity('pubsub', nodeType)) 296 @@ -852,17 +845,33 @@ 297 298 info.append(form.toElement()) 299 300 - d = self.getNodeInfo(requestor, target, nodeIdentifier or '') 301 - d.addCallback(toInfo) 302 - d.addBoth(lambda result: info) 303 + return info 304 + 305 + info = [] 306 + 307 + request = PubSubRequest('discoInfo') 308 + resource = self.resource.locateResource(request) 309 + 310 + if not nodeIdentifier: 311 + info.append(resource.discoIdentity) 312 + info.append(disco.DiscoFeature(disco.NS_DISCO_ITEMS)) 313 + info.extend([disco.DiscoFeature("%s#%s" % (NS_PUBSUB, feature)) 314 + for feature in resource.features]) 315 + 316 + d = resource.getInfo(requestor, target, nodeIdentifier or '') 317 + d.addCallback(toInfo, info) 318 + d.addErrback(log.err) 319 return d 320 321 322 def getDiscoItems(self, requestor, target, nodeIdentifier): 323 - if nodeIdentifier or self.hideNodes: 324 + request = PubSubRequest('discoInfo') 325 + resource = self.resource.locateResource(request) 326 + 327 + if self.hideNodes: 328 return defer.succeed([]) 329 330 - d = self.getNodes(requestor, target) 331 + d = resource.getNodes(requestor, target, nodeIdentifier) 332 d.addCallback(lambda nodes: [disco.DiscoItem(target, node) 333 for node in nodes]) 334 return d 335 @@ -870,91 +879,80 @@ 284 336 285 337 def _onPubSubRequest(self, iq): … … 303 355 + # Process the request itself, 304 356 + try: 305 + handler = getattr(resource, 'pubsub_%s' %request.verb)357 + handler = getattr(resource, request.verb) 306 358 + except AttributeError: 307 359 + # fix lookup feature … … 430 482 431 483 def _makeFields(self, options, values): 432 @@ -9 54,8 +951,8 @@484 @@ -973,8 +971,8 @@ 433 485 return fields 434 486 … … 441 493 form = data_form.Form(formType="form", 442 494 formNamespace=NS_PUBSUB_NODE_CONFIG, 443 @@ -9 64,8 +961,8 @@495 @@ -983,8 +981,8 @@ 444 496 return form 445 497 … … 452 504 453 505 for key, value in values.iteritems(): 454 @@ - 989,93 +986,45@@506 @@ -1008,93 +1006,52 @@ 455 507 return processedValues 456 508 457 509 458 510 - def _on_default(self, request): 511 + def _preProcess_default(self, resource, request): 512 + if request.nodeType not in ('leaf', 'collection'): 513 + raise error.StanzaError('not-acceptable') 514 + else: 515 + return request 516 517 - def toResponse(options): 518 - response = domish.Element((NS_PUBSUB_OWNER, "pubsub")) 519 - default = response.addElement("default") 520 - default.addChild(self._formFromConfiguration(options).toElement()) 521 - return response 522 523 - if request.nodeType not in ('leaf', 'collection'): 524 - return defer.fail(error.StanzaError('not-acceptable')) 459 525 + def _toResponse_default(self, options, resource, request): 460 526 + response = domish.Element((NS_PUBSUB_OWNER, "pubsub")) … … 464 530 + return response 465 531 466 - def toResponse(options): 467 - response = domish.Element((NS_PUBSUB_OWNER, "pubsub")) 468 - default = response.addElement("default") 469 - default.addChild(self._formFromConfiguration(options).toElement()) 470 - return response 471 472 - if request.nodeType not in ('leaf', 'collection'): 473 - return defer.fail(error.StanzaError('not-acceptable')) 532 - d = self.getDefaultConfiguration(request) 533 - d.addCallback(toResponse) 534 - return d 535 474 536 + def _toResponse_configureGet(self, options, resource, request): 475 537 + response = domish.Element((NS_PUBSUB_OWNER, "pubsub")) … … 477 539 + form = self._formFromConfiguration(resource, options) 478 540 + configure.addChild(form.toElement()) 479 480 - d = self.getDefaultConfiguration(request)481 - d.addCallback(toResponse)482 - return d483 + if request.nodeIdentifier:484 + configure["node"] = request.nodeIdentifier485 486 + return response487 541 488 542 - def _on_configureGet(self, request): … … 492 546 - form = self._formFromConfiguration(options) 493 547 - configure.addChild(form.toElement()) 548 + if request.nodeIdentifier: 549 + configure["node"] = request.nodeIdentifier 494 550 495 551 - if request.nodeIdentifier: 496 552 - configure["node"] = request.nodeIdentifier 497 - 553 + return response 554 498 555 - return response 499 - 556 500 557 - d = self.getConfiguration(request) 501 558 - d.addCallback(toResponse) … … 571 628 def _createNotification(self, eventType, service, nodeIdentifier, 572 629 subscriber, subscriptions=None): 573 @@ -1 099,6 +1048,8 @@630 @@ -1118,6 +1075,8 @@ 574 631 575 632 return message … … 580 637 for subscriber, subscriptions, items in notifications: 581 638 message = self._createNotification('items', service, 582 @@ -11 20,65 +1071,90@@639 @@ -1139,65 +1098,96 @@ 583 640 self.send(message) 584 641 … … 586 643 - def getNodeInfo(self, requestor, service, nodeIdentifier): 587 644 - return None 588 + 645 589 646 +class PubSubResource(object): 590 + 647 648 - def getNodes(self, requestor, service): 649 - return [] 591 650 + implements(IPubSubResource) 592 + 651 652 + features = [] 653 + discoIdentity = disco.DiscoIdentity('pubsub', 654 + 'service', 655 + 'Publish-Subscribe Service') 656 657 - def publish(self, request): 658 - raise Unsupported('publish') 659 593 660 + def locateResource(self, request): 594 661 + return self 595 + 596 + 662 663 - def subscribe(self, request): 664 - raise Unsupported('subscribe') 665 597 666 + def getInfo(self, requestor, service, nodeIdentifier): 598 667 + return defer.succeed(None) 599 668 600 601 def getNodes(self, requestor, service):602 return []603 604 605 - def publish(self, request):606 - raise Unsupported('publish')607 -608 -609 - def subscribe(self, request):610 - raise Unsupported('subscribe')611 -612 -613 669 - def unsubscribe(self, request): 614 670 - raise Unsupported('subscribe') 615 - 671 616 672 - 617 673 - def subscriptions(self, request): … … 625 681 - def create(self, request): 626 682 - raise Unsupported('create-nodes') 627 - 628 - 683 + def getNodes(self, requestor, service, nodeIdentifier): 684 + return defer.succeed([]) 685 686 629 687 def getConfigurationOptions(self): 630 688 return {} … … 633 691 - def getDefaultConfiguration(self, request): 634 692 - raise Unsupported('retrieve-default') 635 + def pub sub_publish(self, request):693 + def publish(self, request): 636 694 + return defer.fail(Unsupported('publish')) 637 695 … … 639 697 - def getConfiguration(self, request): 640 698 - raise Unsupported('config-node') 641 + def pubsub_subscribe(self, request):699 + def subscribe(self, request): 642 700 + return defer.fail(Unsupported('subscribe')) 643 701 … … 645 703 - def setConfiguration(self, request): 646 704 - raise Unsupported('config-node') 647 + def pubsub_unsubscribe(self, request):705 + def unsubscribe(self, request): 648 706 + return defer.fail(Unsupported('subscribe')) 649 650 651 - def items(self, request): 707 + 708 + 709 + def subscriptions(self, request): 710 + return defer.fail(Unsupported('retrieve-subscriptions')) 711 + 712 + 713 + def affiliations(self, request): 714 + return defer.fail(Unsupported('retrieve-affiliations')) 715 + 716 + 717 + def create(self, request): 718 + return defer.fail(Unsupported('create-nodes')) 719 + 720 + 721 + def default(self, request): 722 + return defer.fail(Unsupported('retrieve-default')) 723 + 724 + 725 + def configureGet(self, request): 726 + return defer.fail(Unsupported('config-node')) 727 + 728 + 729 + def configureSet(self, request): 730 + return defer.fail(Unsupported('config-node')) 731 732 733 def items(self, request): 652 734 - raise Unsupported('retrieve-items') 653 + def pubsub_subscriptions(self, request): 654 + return defer.fail(Unsupported('retrieve-subscriptions')) 655 656 657 - def retract(self, request): 735 + return defer.fail(Unsupported('retrieve-items')) 736 737 738 def retract(self, request): 658 739 - raise Unsupported('retract-items') 659 + def pubsub_affiliations(self, request): 660 + return defer.fail(Unsupported('retrieve-affiliations')) 661 662 663 - def purge(self, request): 740 + return defer.fail(Unsupported('retract-items')) 741 742 743 def purge(self, request): 664 744 - raise Unsupported('purge-nodes') 665 + def pubsub_create(self, request): 666 + return defer.fail(Unsupported('create-nodes')) 667 668 669 - def delete(self, request): 745 + return defer.fail(Unsupported('purge-nodes')) 746 747 748 def delete(self, request): 670 749 - raise Unsupported('delete-nodes') 671 + def pubsub_default(self, request):672 + return defer.fail(Unsupported('retrieve-default'))673 +674 +675 + def pubsub_configureGet(self, request):676 + return defer.fail(Unsupported('config-node'))677 +678 +679 + def pubsub_configureSet(self, request):680 + return defer.fail(Unsupported('config-node'))681 +682 +683 + def pubsub_items(self, request):684 + return defer.fail(Unsupported('retrieve-items'))685 +686 +687 + def pubsub_retract(self, request):688 + return defer.fail(Unsupported('retract-items'))689 +690 +691 + def pubsub_purge(self, request):692 + return defer.fail(Unsupported('purge-nodes'))693 +694 +695 + def pubsub_delete(self, request):696 750 + return defer.fail(Unsupported('delete-nodes')) 697 751 + 698 752 + 699 + def pubsub_affiliationsGet(self, request):753 + def affiliationsGet(self, request): 700 754 + return defer.fail(Unsupported('modify-affiliations')) 701 755 + 702 756 + 703 + def pubsub_affiliationsSet(self, request):757 + def affiliationsSet(self, request): 704 758 + return defer.fail(Unsupported('modify-affiliations')) 705 759 + 706 760 + 707 + def pubsub_subscriptionsGet(self, request):761 + def subscriptionsGet(self, request): 708 762 + return defer.fail(Unsupported('manage-subscriptions')) 709 763 + 710 764 + 711 + def pubsub_subscriptionsSet(self, request):765 + def subscriptionsSet(self, request): 712 766 + return defer.fail(Unsupported('manage-subscriptions')) 713 diff -r dc8ed1ff55d7 wokkel/test/test_pubsub.py 714 --- a/wokkel/test/test_pubsub.py Wed Mar 18 09:26:24 2009 +0100 715 +++ b/wokkel/test/test_pubsub.py Wed Mar 18 20:51:58 2009 +0100 716 @@ -600,7 +600,8 @@ 767 diff -r 2ea6196efcdc wokkel/test/test_pubsub.py 768 --- a/wokkel/test/test_pubsub.py Wed Mar 25 18:14:07 2009 +0100 769 +++ b/wokkel/test/test_pubsub.py Mon Mar 30 08:35:05 2009 +0200 770 @@ -13,7 +13,7 @@ 771 from twisted.words.protocols.jabber import error 772 from twisted.words.protocols.jabber.jid import JID 773 774 -from wokkel import data_form, iwokkel, pubsub, shim 775 +from wokkel import data_form, disco, iwokkel, pubsub, shim 776 from wokkel.generic import parseXml 777 from wokkel.test.helpers import TestableRequestHandlerMixin, XmlStreamStub 778 779 @@ -1225,7 +1225,8 @@ 717 780 718 781 def setUp(self): … … 724 787 725 788 def test_interface(self): 726 @@ -694,8 +695,8 @@ 727 self.assertEqual([], request.items) 789 @@ -1263,19 +1264,120 @@ 790 Test getDiscoInfo calls getNodeInfo and returns some minimal info. 791 """ 792 def cb(info): 793 - self.assertEqual(2, len(info)) 794 + discoInfo = disco.DiscoInfo() 795 + for item in info: 796 + discoInfo.append(item) 797 + self.assertIn(('pubsub', 'service'), discoInfo.identities) 798 + self.assertIn(disco.NS_DISCO_ITEMS, discoInfo.features) 799 800 - def getNodeInfo(requestor, target, nodeIdentifier): 801 - return defer.succeed(None) 802 - 803 - self.service.getNodeInfo = getNodeInfo 804 d = self.service.getDiscoInfo(JID('user@example.org/home'), 805 JID('pubsub.example.org'), '') 806 d.addCallback(cb) 807 return d 808 809 810 - def test_onPublish(self): 811 + def test_getDiscoInfoNodeType(self): 812 + """ 813 + Test getDiscoInfo calls getNodeInfo and returns some minimal info. 814 + """ 815 + def cb(info): 816 + discoInfo = disco.DiscoInfo() 817 + for item in info: 818 + discoInfo.append(item) 819 + self.assertIn(('pubsub', 'collection'), discoInfo.identities) 820 + 821 + def getInfo(requestor, target, nodeIdentifier): 822 + return defer.succeed({'type': 'collection', 823 + 'meta-data': {}}) 824 + 825 + self.resource.getInfo = getInfo 826 + d = self.service.getDiscoInfo(JID('user@example.org/home'), 827 + JID('pubsub.example.org'), '') 828 + d.addCallback(cb) 829 + return d 830 + 831 + 832 + def test_getDiscoInfoResourceFeatures(self): 833 + """ 834 + Test getDiscoInfo calls getNodeInfo and returns some minimal info. 835 + """ 836 + def cb(info): 837 + discoInfo = disco.DiscoInfo() 838 + for item in info: 839 + discoInfo.append(item) 840 + self.assertIn('http://jabber.org/protocol/pubsub#publish', 841 + discoInfo.features) 842 + 843 + self.resource.features = ['publish'] 844 + d = self.service.getDiscoInfo(JID('user@example.org/home'), 845 + JID('pubsub.example.org'), '') 846 + d.addCallback(cb) 847 + return d 848 + 849 + 850 + def test_getDiscoItemsRoot(self): 851 + """ 852 + Test getDiscoItems on the root node. 853 + """ 854 + def getNodes(requestor, service, nodeIdentifier): 855 + return defer.succeed(['node1', 'node2']) 856 + 857 + def cb(items): 858 + self.assertEqual(2, len(items)) 859 + item1, item2 = items 860 + 861 + self.assertEqual(JID('pubsub.example.org'), item1.entity) 862 + self.assertEqual('node1', item1.nodeIdentifier) 863 + 864 + self.assertEqual(JID('pubsub.example.org'), item2.entity) 865 + self.assertEqual('node2', item2.nodeIdentifier) 866 + 867 + self.resource.getNodes = getNodes 868 + d = self.service.getDiscoItems(JID('user@example.org/home'), 869 + JID('pubsub.example.org'), 870 + '') 871 + d.addCallback(cb) 872 + return d 873 + 874 + 875 + def test_getDiscoItemsRootHideNodes(self): 876 + """ 877 + Test getDiscoItems on the root node. 878 + """ 879 + def getNodes(requestor, service, nodeIdentifier): 880 + raise Exception("Unexpected call to getNodes") 881 + 882 + def cb(items): 883 + self.assertEqual([], items) 884 + 885 + self.service.hideNodes = True 886 + self.resource.getNodes = getNodes 887 + d = self.service.getDiscoItems(JID('user@example.org/home'), 888 + JID('pubsub.example.org'), 889 + '') 890 + d.addCallback(cb) 891 + return d 892 + 893 + 894 + def test_getDiscoItemsNonRoot(self): 895 + """ 896 + Test getDiscoItems on a non-root node. 897 + """ 898 + def getNodes(requestor, service, nodeIdentifier): 899 + return defer.succeed(['node1', 'node2']) 900 + 901 + def cb(items): 902 + self.assertEqual(2, len(items)) 903 + 904 + self.resource.getNodes = getNodes 905 + d = self.service.getDiscoItems(JID('user@example.org/home'), 906 + JID('pubsub.example.org'), 907 + 'test') 908 + d.addCallback(cb) 909 + return d 910 + 911 + 912 + def test_on_publish(self): 913 """ 914 A publish request should result in L{PubSubService.publish} being 915 called. 916 @@ -1293,12 +1395,12 @@ 917 def publish(request): 728 918 return defer.succeed(None) 729 919 730 920 - self.service.publish = publish 731 921 - verify.verifyObject(iwokkel.IPubSubService, self.service) 732 + self.resource.pub sub_publish = publish922 + self.resource.publish = publish 733 923 + verify.verifyObject(iwokkel.IPubSubResource, self.resource) 734 924 return self.handleRequest(xml) 735 925 736 926 737 @@ -722,8 +723,8 @@ 738 self.assertEqual(u'item2', request.items[1]["id"]) 739 return defer.succeed(None) 740 741 - self.service.publish = publish 742 - verify.verifyObject(iwokkel.IPubSubService, self.service) 743 + self.resource.pubsub_publish = publish 744 + verify.verifyObject(iwokkel.IPubSubResource, self.resource) 745 return self.handleRequest(xml) 746 747 748 @@ -759,8 +760,8 @@ 927 - def test_onSubscribe(self): 928 + def test_on_subscribe(self): 929 """ 930 A successful subscription should return the current subscription. 931 """ 932 @@ -1326,14 +1428,14 @@ 749 933 self.assertEqual('user@example.org/Home', subscription['jid']) 750 934 self.assertEqual('subscribed', subscription['subscription']) … … 752 936 - self.service.subscribe = subscribe 753 937 - verify.verifyObject(iwokkel.IPubSubService, self.service) 754 + self.resource. pubsub_subscribe = subscribe938 + self.resource.subscribe = subscribe 755 939 + verify.verifyObject(iwokkel.IPubSubResource, self.resource) 756 940 d = self.handleRequest(xml) 757 941 d.addCallback(cb) 758 942 return d 759 @@ -789,8 +790,8 @@ 943 944 945 - def test_onSubscribeEmptyNode(self): 946 + def test_on_subscribeEmptyNode(self): 947 """ 948 A successful subscription on root node should return no node attribute. 949 """ 950 @@ -1355,14 +1457,14 @@ 760 951 def cb(element): 761 952 self.assertFalse(element.subscription.hasAttribute('node')) … … 763 954 - self.service.subscribe = subscribe 764 955 - verify.verifyObject(iwokkel.IPubSubService, self.service) 765 + self.resource. pubsub_subscribe = subscribe956 + self.resource.subscribe = subscribe 766 957 + verify.verifyObject(iwokkel.IPubSubResource, self.resource) 767 958 d = self.handleRequest(xml) 768 959 d.addCallback(cb) 769 960 return d 770 @@ -820,8 +821,8 @@ 961 962 963 - def test_onUnsubscribe(self): 964 + def test_on_unsubscribe(self): 965 """ 966 A successful unsubscription should return an empty response. 967 """ 968 @@ -1382,14 +1484,14 @@ 771 969 def cb(element): 772 970 self.assertIdentical(None, element) … … 774 972 - self.service.unsubscribe = unsubscribe 775 973 - verify.verifyObject(iwokkel.IPubSubService, self.service) 776 + self.resource. pubsub_unsubscribe = unsubscribe974 + self.resource.unsubscribe = unsubscribe 777 975 + verify.verifyObject(iwokkel.IPubSubResource, self.resource) 778 976 d = self.handleRequest(xml) 779 977 d.addCallback(cb) 780 978 return d 781 @@ -914,8 +915,8 @@ 782 'subscribed') 783 return defer.succeed([subscription]) 784 979 980 981 - def test_onOptionsGet(self): 982 + def test_on_optionsGet(self): 983 """ 984 Getting subscription options is not supported. 985 """ 986 @@ -1414,7 +1516,7 @@ 987 return d 988 989 990 - def test_onOptionsSet(self): 991 + def test_on_optionsSet(self): 992 """ 993 Setting subscription options is not supported. 994 """ 995 @@ -1446,7 +1548,7 @@ 996 return d 997 998 999 - def test_onSubscriptions(self): 1000 + def test_on_subscriptions(self): 1001 """ 1002 A subscriptions request should result in 1003 L{PubSubService.subscriptions} being called and the result prepared 1004 @@ -1462,6 +1564,11 @@ 1005 </iq> 1006 """ 1007 1008 + def subscriptions(request): 1009 + subscription = pubsub.Subscription('test', JID('user@example.org'), 1010 + 'subscribed') 1011 + return defer.succeed([subscription]) 1012 + 1013 def cb(element): 1014 self.assertEqual('pubsub', element.name) 1015 self.assertEqual(NS_PUBSUB, element.uri) 1016 @@ -1475,20 +1582,14 @@ 1017 self.assertEqual('test', subscription['node']) 1018 self.assertEqual('subscribed', subscription['subscription']) 1019 1020 - 1021 - def subscriptions(request): 1022 - subscription = pubsub.Subscription('test', JID('user@example.org'), 1023 - 'subscribed') 1024 - return defer.succeed([subscription]) 1025 - 785 1026 - self.service.subscriptions = subscriptions 786 1027 - verify.verifyObject(iwokkel.IPubSubService, self.service) 787 + self.resource. pubsub_subscriptions = subscriptions1028 + self.resource.subscriptions = subscriptions 788 1029 + verify.verifyObject(iwokkel.IPubSubResource, self.resource) 789 1030 d = self.handleRequest(xml) 790 1031 d.addCallback(cb) 791 1032 return d 792 @@ -956,8 +957,8 @@ 793 affiliation = ('test', 'owner') 794 return defer.succeed([affiliation]) 795 1033 1034 1035 - def test_onAffiliations(self): 1036 + def test_on_affiliations(self): 1037 """ 1038 A subscriptions request should result in 1039 L{PubSubService.affiliations} being called and the result prepared 1040 @@ -1504,6 +1605,10 @@ 1041 </iq> 1042 """ 1043 1044 + def affiliations(request): 1045 + affiliation = ('test', 'owner') 1046 + return defer.succeed([affiliation]) 1047 + 1048 def cb(element): 1049 self.assertEqual('pubsub', element.name) 1050 self.assertEqual(NS_PUBSUB, element.uri) 1051 @@ -1516,19 +1621,14 @@ 1052 self.assertEqual('test', affiliation['node']) 1053 self.assertEqual('owner', affiliation['affiliation']) 1054 1055 - 1056 - def affiliations(request): 1057 - affiliation = ('test', 'owner') 1058 - return defer.succeed([affiliation]) 1059 - 796 1060 - self.service.affiliations = affiliations 797 1061 - verify.verifyObject(iwokkel.IPubSubService, self.service) 798 + self.resource. pubsub_affiliations = affiliations1062 + self.resource.affiliations = affiliations 799 1063 + verify.verifyObject(iwokkel.IPubSubResource, self.resource) 800 1064 d = self.handleRequest(xml) 801 1065 d.addCallback(cb) 802 1066 return d 803 @@ -986,8 +987,8 @@ 1067 1068 1069 - def test_onCreate(self): 1070 + def test_on_create(self): 1071 """ 1072 Replies to create node requests don't return the created node. 1073 """ 1074 @@ -1548,14 +1648,14 @@ 804 1075 def cb(element): 805 1076 self.assertIdentical(None, element) … … 807 1078 - self.service.create = create 808 1079 - verify.verifyObject(iwokkel.IPubSubService, self.service) 809 + self.resource. pubsub_create = create1080 + self.resource.create = create 810 1081 + verify.verifyObject(iwokkel.IPubSubResource, self.resource) 811 1082 d = self.handleRequest(xml) 812 1083 d.addCallback(cb) 813 1084 return d 814 @@ -1017,8 +1018,8 @@ 1085 1086 1087 - def test_onCreateChanged(self): 1088 + def test_on_createChanged(self): 1089 """ 1090 Replies to create node requests return the created node if changed. 1091 """ 1092 @@ -1579,14 +1679,14 @@ 815 1093 self.assertEqual(u'myrenamednode', 816 1094 element.create.getAttribute('node')) … … 818 1096 - self.service.create = create 819 1097 - verify.verifyObject(iwokkel.IPubSubService, self.service) 820 + self.resource. pubsub_create = create1098 + self.resource.create = create 821 1099 + verify.verifyObject(iwokkel.IPubSubResource, self.resource) 822 1100 d = self.handleRequest(xml) 823 1101 d.addCallback(cb) 824 1102 return d 825 @@ -1048,8 +1049,8 @@ 1103 1104 1105 - def test_onCreateInstant(self): 1106 + def test_on_createInstant(self): 1107 """ 1108 Replies to create instant node requests return the created node. 1109 """ 1110 @@ -1609,14 +1709,14 @@ 826 1111 self.assertEqual(NS_PUBSUB, element.create.uri) 827 1112 self.assertEqual(u'random', element.create.getAttribute('node')) … … 829 1114 - self.service.create = create 830 1115 - verify.verifyObject(iwokkel.IPubSubService, self.service) 831 + self.resource. pubsub_create = create1116 + self.resource.create = create 832 1117 + verify.verifyObject(iwokkel.IPubSubResource, self.resource) 833 1118 d = self.handleRequest(xml) 834 1119 d.addCallback(cb) 835 1120 return d 836 @@ -1093,9 +1094,9 @@ 1121 1122 1123 - def test_onDefault(self): 1124 + def test_on_default(self): 1125 """ 1126 A default request should result in 1127 L{PubSubService.getDefaultConfiguration} being called. 1128 @@ -1641,7 +1741,7 @@ 1129 "label": "Deliver payloads with event notifications"} 1130 } 1131 1132 - def getDefaultConfiguration(request): 1133 + def default(request): 1134 return defer.succeed({}) 1135 1136 def cb(element): 1137 @@ -1651,15 +1751,15 @@ 837 1138 form = data_form.Form.fromElement(element.default.x) 838 1139 self.assertEqual(NS_PUBSUB_CONFIG, form.formNamespace) … … 842 1143 - verify.verifyObject(iwokkel.IPubSubService, self.service) 843 1144 + self.resource.getConfigurationOptions = getConfigurationOptions 844 + self.resource. pubsub_default = getDefaultConfiguration1145 + self.resource.default = default 845 1146 + verify.verifyObject(iwokkel.IPubSubResource, self.resource) 846 1147 d = self.handleRequest(xml) 847 1148 d.addCallback(cb) 848 1149 return d 849 @@ -1143,9 +1144,9 @@ 850 form = data_form.Form.fromElement(element.default.x) 851 self.assertEqual(NS_PUBSUB_CONFIG, form.formNamespace) 1150 1151 1152 - def test_onDefaultCollection(self): 1153 + def test_on_defaultCollection(self): 1154 """ 1155 Responses to default requests should depend on passed node type. 1156 """ 1157 @@ -1690,19 +1790,19 @@ 1158 "label": "Deliver payloads with event notifications"} 1159 } 1160 1161 - def getDefaultConfiguration(request): 1162 + def default(request): 1163 return defer.succeed({}) 852 1164 853 1165 - self.service.getConfigurationOptions = getConfigurationOptions … … 855 1167 - verify.verifyObject(iwokkel.IPubSubService, self.service) 856 1168 + self.resource.getConfigurationOptions = getConfigurationOptions 857 + self.resource.pubsub_default = getDefaultConfiguration 858 + verify.verifyObject(iwokkel.IPubSubResource, self.resource) 859 d = self.handleRequest(xml) 860 d.addCallback(cb) 861 return d 862 @@ -1182,8 +1183,8 @@ 1169 + self.resource.default = default 1170 + verify.verifyObject(iwokkel.IPubSubResource, self.resource) 1171 return self.handleRequest(xml) 1172 1173 1174 - def test_onDefaultUnknownNodeType(self): 1175 + def test_on_defaultUnknownNodeType(self): 1176 """ 1177 A default request should result in 1178 - L{PubSubService.getDefaultConfiguration} being called. 1179 + L{PubSubResource.default} being called. 1180 """ 1181 1182 xml = """ 1183 @@ -1724,24 +1824,25 @@ 1184 </iq> 1185 """ 1186 1187 - def getDefaultConfiguration(request): 1188 + def default(request): 1189 self.fail("Unexpected call to getConfiguration") 1190 863 1191 def cb(result): 864 1192 self.assertEquals('not-acceptable', result.condition) … … 866 1194 - self.service.getDefaultConfiguration = getDefaultConfiguration 867 1195 - verify.verifyObject(iwokkel.IPubSubService, self.service) 868 + self.resource. pubsub_default = getDefaultConfiguration1196 + self.resource.default = default 869 1197 + verify.verifyObject(iwokkel.IPubSubResource, self.resource) 870 1198 d = self.handleRequest(xml) 871 1199 self.assertFailure(d, error.StanzaError) 872 1200 d.addCallback(cb) 873 @@ -1257,9 +1258,9 @@ 1201 return d 1202 1203 1204 - def test_onConfigureGet(self): 1205 + def test_on_configureGet(self): 1206 """ 1207 - On a node configuration get request L{PubSubService.getConfiguration} 1208 - is called and results in a data form with the configuration. 1209 + On a node configuration get 1210 + requestL{PubSubResource.configureGet} is called and results in a 1211 + data form with the configuration. 1212 """ 1213 1214 xml = """ 1215 @@ -1766,7 +1867,7 @@ 1216 "label": "Owner of the node"} 1217 } 1218 1219 - def getConfiguration(request): 1220 + def configureGet(request): 1221 return defer.succeed({'pubsub#deliver_payloads': '0', 1222 'pubsub#persist_items': '1', 1223 'pubsub#owner': JID('user@example.org'), 1224 @@ -1800,19 +1901,18 @@ 1225 874 1226 self.assertNotIn('x-myfield', fields) 875 1227 876 1228 - 877 1229 - self.service.getConfigurationOptions = getConfigurationOptions 878 1230 - self.service.getConfiguration = getConfiguration 879 1231 - verify.verifyObject(iwokkel.IPubSubService, self.service) 880 1232 + self.resource.getConfigurationOptions = getConfigurationOptions 881 + self.resource. pubsub_configureGet = getConfiguration1233 + self.resource.configureGet = configureGet 882 1234 + verify.verifyObject(iwokkel.IPubSubResource, self.resource) 883 1235 d = self.handleRequest(xml) 884 1236 d.addCallback(cb) 885 1237 return d 886 @@ -1306,9 +1307,9 @@ 1238 1239 1240 - def test_onConfigureSet(self): 1241 + def test_on_configureSet(self): 1242 """ 1243 On a node configuration set request the Data Form is parsed and 1244 - L{PubSubService.setConfiguration} is called with the passed options. 1245 + L{PubSubResource.configureSet} is called with the passed options. 1246 """ 1247 1248 xml = """ 1249 @@ -1842,21 +1942,21 @@ 1250 "label": "Deliver payloads with event notifications"} 1251 } 1252 1253 - def setConfiguration(request): 1254 + def configureSet(request): 1255 self.assertEqual({'pubsub#deliver_payloads': False, 887 1256 'pubsub#persist_items': True}, request.options) 888 1257 return defer.succeed(None) … … 892 1261 - verify.verifyObject(iwokkel.IPubSubService, self.service) 893 1262 + self.resource.getConfigurationOptions = getConfigurationOptions 894 + self.resource. pubsub_configureSet = setConfiguration1263 + self.resource.configureSet = configureSet 895 1264 + verify.verifyObject(iwokkel.IPubSubResource, self.resource) 896 1265 return self.handleRequest(xml) 897 1266 898 1267 899 @@ -1336,8 +1337,8 @@ 900 def setConfiguration(request): 1268 - def test_onConfigureSetCancel(self): 1269 + def test_on_configureSetCancel(self): 1270 """ 1271 - The node configuration is cancelled, L{PubSubService.setConfiguration} 1272 - not called. 1273 + The node configuration is cancelled, 1274 + L{PubSubResource.configureSet} not called. 1275 """ 1276 1277 xml = """ 1278 @@ -1874,15 +1974,15 @@ 1279 </iq> 1280 """ 1281 1282 - def setConfiguration(request): 1283 + def configureSet(request): 901 1284 self.fail("Unexpected call to setConfiguration") 902 1285 903 1286 - self.service.setConfiguration = setConfiguration 904 1287 - verify.verifyObject(iwokkel.IPubSubService, self.service) 905 + self.resource. pubsub_configureSet = setConfiguration1288 + self.resource.configureSet = configureSet 906 1289 + verify.verifyObject(iwokkel.IPubSubResource, self.resource) 907 1290 return self.handleRequest(xml) 908 1291 909 1292 910 @@ -1377,9 +1378,9 @@ 1293 - def test_onConfigureSetIgnoreUnknown(self): 1294 + def test_on_configureSetIgnoreUnknown(self): 1295 """ 1296 On a node configuration set request unknown fields should be ignored. 1297 """ 1298 @@ -1914,17 +2014,17 @@ 1299 "label": "Deliver payloads with event notifications"} 1300 } 1301 1302 - def setConfiguration(request): 1303 + def configureSet(request): 911 1304 self.assertEquals(['pubsub#deliver_payloads'], 912 1305 request.options.keys()) … … 916 1309 - verify.verifyObject(iwokkel.IPubSubService, self.service) 917 1310 + self.resource.getConfigurationOptions = getConfigurationOptions 918 + self.resource. pubsub_configureSet = setConfiguration1311 + self.resource.configureSet = configureSet 919 1312 + verify.verifyObject(iwokkel.IPubSubResource, self.resource) 920 1313 return self.handleRequest(xml) 921 1314 922 1315 923 @@ -1445,7 +1446,8 @@ 1316 - def test_onConfigureSetBadFormType(self): 1317 + def test_on_configureSetBadFormType(self): 1318 """ 1319 On a node configuration set request unknown fields should be ignored. 1320 """ 1321 @@ -1955,7 +2055,7 @@ 1322 return d 1323 1324 1325 - def test_onItems(self): 1326 + def test_on_items(self): 1327 """ 1328 On a items request, return all items for the given node. 1329 """ 1330 @@ -1981,16 +2081,17 @@ 924 1331 self.assertEqual(NS_PUBSUB, item.uri) 925 1332 self.assertEqual('current', item['id']) 926 1333 927 1334 - self.service.items = items 928 + self.resource. pubsub_items = items1335 + self.resource.items = items 929 1336 + verify.verifyObject(iwokkel.IPubSubResource, self.resource) 930 1337 d = self.handleRequest(xml) 931 1338 d.addCallback(cb) 932 1339 return d 933 @@ -1476,7 +1478,8 @@ 934 self.assertEqual(['item1', 'item2'], request.itemIdentifiers) 1340 1341 1342 - def test_onRetract(self): 1343 + def test_on_retract(self): 1344 """ 1345 - A retract request should result in L{PubSubService.retract} being 1346 - called. 1347 + A retract request should result in L{PubSubResource.retract} 1348 + being called. 1349 """ 1350 1351 xml = """ 1352 @@ -2008,13 +2109,14 @@ 1353 def retract(request): 935 1354 return defer.succeed(None) 936 1355 937 1356 - self.service.retract = retract 938 + self.resource. pubsub_retract = retract1357 + self.resource.retract = retract 939 1358 + verify.verifyObject(iwokkel.IPubSubResource, self.resource) 940 1359 return self.handleRequest(xml) 941 1360 942 1361 943 @@ -1501,7 +1504,8 @@ 944 self.assertEqual('test', request.nodeIdentifier) 1362 - def test_onPurge(self): 1363 + def test_on_purge(self): 1364 """ 1365 - A purge request should result in L{PubSubService.purge} being 1366 + A purge request should result in L{PubSubResource.purge} being 1367 called. 1368 """ 1369 1370 @@ -2030,13 +2132,14 @@ 1371 def purge(request): 945 1372 return defer.succeed(None) 946 1373 947 1374 - self.service.purge = purge 948 + self.resource.pu bsub_purge = purge1375 + self.resource.purge = purge 949 1376 + verify.verifyObject(iwokkel.IPubSubResource, self.resource) 950 1377 return self.handleRequest(xml) 951 1378 952 1379 953 @@ -1526,7 +1530,8 @@ 954 self.assertEqual('test', request.nodeIdentifier) 1380 - def test_onDelete(self): 1381 + def test_on_delete(self): 1382 """ 1383 - A delete request should result in L{PubSubService.delete} being 1384 + A delete request should result in L{PubSubResource.delete} being 1385 called. 1386 """ 1387 1388 @@ -2052,7 +2155,8 @@ 1389 def delete(request): 955 1390 return defer.succeed(None) 956 1391 957 1392 - self.service.delete = delete 958 + self.resource. pubsub_delete = delete1393 + self.resource.delete = delete 959 1394 + verify.verifyObject(iwokkel.IPubSubResource, self.resource) 960 1395 return self.handleRequest(xml) 961 1396 962 1397 963 @@ -1687,7 +1692,7 @@ 964 1398 @@ -2103,7 +2207,7 @@ 1399 self.assertEqual(redirectURI, message.event.delete.redirect['uri']) 1400 1401 1402 - def test_onSubscriptionsGet(self): 1403 + def test_on_subscriptionsGet(self): 1404 """ 1405 Getting subscription options is not supported. 1406 """ 1407 @@ -2130,7 +2234,7 @@ 1408 return d 1409 1410 1411 - def test_onSubscriptionsSet(self): 1412 + def test_on_subscriptionsSet(self): 1413 """ 1414 Setting subscription options is not supported. 1415 """ 1416 @@ -2157,7 +2261,7 @@ 1417 return d 1418 1419 1420 - def test_onAffiliationsGet(self): 1421 + def test_on_affiliationsGet(self): 1422 """ 1423 Getting subscription options is not supported. 1424 """ 1425 @@ -2184,7 +2288,7 @@ 1426 return d 1427 1428 1429 - def test_onAffiliationsSet(self): 1430 + def test_on_affiliationsSet(self): 1431 """ 1432 Setting subscription options is not supported. 1433 """ 1434 @@ -2211,18 +2315,38 @@ 1435 return d 1436 1437 1438 + 1439 +class PubSubResourceTest(unittest.TestCase): 1440 + 1441 + def setUp(self): 1442 + self.resource = pubsub.PubSubResource() 1443 + 1444 + 1445 + def test_interface(self): 1446 + """ 1447 + Do instances of L{pubsub.PubSubResource} provide L{iwokkel.IPubSubResource}? 1448 + """ 1449 + verify.verifyObject(iwokkel.IPubSubResource, self.resource) 1450 + 1451 + 1452 + def test_getNodes(self): 1453 + """ 1454 + Default getNodes returns an empty list. 1455 + """ 1456 + def cb(nodes): 1457 + self.assertEquals([], nodes) 1458 + 1459 + d = self.resource.getNodes(JID('user@example.org/home'), 1460 + JID('pubsub.example.org'), 1461 + '') 1462 + d.addCallback(cb) 1463 + return d 1464 + 1465 + 965 1466 def test_publish(self): 966 1467 """ 967 1468 - Non-overridden L{PubSubService.publish} yields unsupported error. 968 + Non-overridden L{PubSubResource.publish} yields unsupported error. 969 """ 970 971 xml = """ 1469 - """ 1470 - 1471 - xml = """ 1472 - <iq type='set' to='pubsub.example.org' 1473 - from='user@example.org'> 1474 - <pubsub xmlns='http://jabber.org/protocol/pubsub'> 1475 - <publish node='mynode'/> 1476 - </pubsub> 1477 - </iq> 1478 + Non-overridden L{PubSubResource.publish} yields unsupported 1479 + error. 1480 """ 1481 1482 def cb(result): 1483 @@ -2231,7 +2355,7 @@ 1484 self.assertEquals(NS_PUBSUB_ERRORS, result.appCondition.uri) 1485 self.assertEquals('publish', result.appCondition['feature']) 1486 1487 - d = self.handleRequest(xml) 1488 + d = self.resource.publish(pubsub.PubSubRequest()) 1489 self.assertFailure(d, error.StanzaError) 1490 d.addCallback(cb) 1491 return d 1492 @@ -2239,16 +2363,7 @@ 1493 1494 def test_subscribe(self): 1495 """ 1496 - Non-overridden L{PubSubService.subscribe} yields unsupported error. 1497 - """ 1498 - 1499 - xml = """ 1500 - <iq type='set' to='pubsub.example.org' 1501 - from='user@example.org'> 1502 - <pubsub xmlns='http://jabber.org/protocol/pubsub'> 1503 - <subscribe node='test' jid='user@example.org/Home'/> 1504 - </pubsub> 1505 - </iq> 1506 + Non-overridden subscriptions yields unsupported error. 1507 """ 1508 1509 def cb(result): 1510 @@ -2257,7 +2372,7 @@ 1511 self.assertEquals(NS_PUBSUB_ERRORS, result.appCondition.uri) 1512 self.assertEquals('subscribe', result.appCondition['feature']) 1513 1514 - d = self.handleRequest(xml) 1515 + d = self.resource.subscribe(pubsub.PubSubRequest()) 1516 self.assertFailure(d, error.StanzaError) 1517 d.addCallback(cb) 1518 return d 1519 @@ -2265,16 +2380,7 @@ 1520 1521 def test_unsubscribe(self): 1522 """ 1523 - Non-overridden L{PubSubService.unsubscribe} yields unsupported error. 1524 - """ 1525 - 1526 - xml = """ 1527 - <iq type='set' to='pubsub.example.org' 1528 - from='user@example.org'> 1529 - <pubsub xmlns='http://jabber.org/protocol/pubsub'> 1530 - <unsubscribe node='test' jid='user@example.org/Home'/> 1531 - </pubsub> 1532 - </iq> 1533 + Non-overridden unsubscribe yields unsupported error. 1534 """ 1535 1536 def cb(result): 1537 @@ -2283,7 +2389,7 @@ 1538 self.assertEquals(NS_PUBSUB_ERRORS, result.appCondition.uri) 1539 self.assertEquals('subscribe', result.appCondition['feature']) 1540 1541 - d = self.handleRequest(xml) 1542 + d = self.resource.unsubscribe(pubsub.PubSubRequest()) 1543 self.assertFailure(d, error.StanzaError) 1544 d.addCallback(cb) 1545 return d 1546 @@ -2291,16 +2397,7 @@ 1547 1548 def test_subscriptions(self): 1549 """ 1550 - Non-overridden L{PubSubService.subscriptions} yields unsupported error. 1551 - """ 1552 - 1553 - xml = """ 1554 - <iq type='get' to='pubsub.example.org' 1555 - from='user@example.org'> 1556 - <pubsub xmlns='http://jabber.org/protocol/pubsub'> 1557 - <subscriptions/> 1558 - </pubsub> 1559 - </iq> 1560 + Non-overridden subscriptions yields unsupported error. 1561 """ 1562 1563 def cb(result): 1564 @@ -2310,7 +2407,7 @@ 1565 self.assertEquals('retrieve-subscriptions', 1566 result.appCondition['feature']) 1567 1568 - d = self.handleRequest(xml) 1569 + d = self.resource.subscriptions(pubsub.PubSubRequest()) 1570 self.assertFailure(d, error.StanzaError) 1571 d.addCallback(cb) 1572 return d 1573 @@ -2318,16 +2415,7 @@ 1574 1575 def test_affiliations(self): 1576 """ 1577 - Non-overridden L{PubSubService.affiliations} yields unsupported error. 1578 - """ 1579 - 1580 - xml = """ 1581 - <iq type='get' to='pubsub.example.org' 1582 - from='user@example.org'> 1583 - <pubsub xmlns='http://jabber.org/protocol/pubsub'> 1584 - <affiliations/> 1585 - </pubsub> 1586 - </iq> 1587 + Non-overridden affiliations yields unsupported error. 1588 """ 1589 1590 def cb(result): 1591 @@ -2337,7 +2425,7 @@ 1592 self.assertEquals('retrieve-affiliations', 1593 result.appCondition['feature']) 1594 1595 - d = self.handleRequest(xml) 1596 + d = self.resource.affiliations(pubsub.PubSubRequest()) 1597 self.assertFailure(d, error.StanzaError) 1598 d.addCallback(cb) 1599 return d 1600 @@ -2345,16 +2433,7 @@ 1601 1602 def test_create(self): 1603 """ 1604 - Non-overridden L{PubSubService.create} yields unsupported error. 1605 - """ 1606 - 1607 - xml = """ 1608 - <iq type='set' to='pubsub.example.org' 1609 - from='user@example.org'> 1610 - <pubsub xmlns='http://jabber.org/protocol/pubsub'> 1611 - <create node='mynode'/> 1612 - </pubsub> 1613 - </iq> 1614 + Non-overridden create yields unsupported error. 1615 """ 1616 1617 def cb(result): 1618 @@ -2363,87 +2442,51 @@ 1619 self.assertEquals(NS_PUBSUB_ERRORS, result.appCondition.uri) 1620 self.assertEquals('create-nodes', result.appCondition['feature']) 1621 1622 - d = self.handleRequest(xml) 1623 + d = self.resource.create(pubsub.PubSubRequest()) 1624 self.assertFailure(d, error.StanzaError) 1625 d.addCallback(cb) 1626 return d 1627 1628 1629 - def test_getDefaultConfiguration(self): 1630 + def test_default(self): 1631 """ 1632 - Non-overridden L{PubSubService.getDefaultConfiguration} yields 1633 - unsupported error. 1634 - """ 1635 - 1636 - xml = """ 1637 - <iq type='get' to='pubsub.example.org' 1638 - from='user@example.org'> 1639 - <pubsub xmlns='http://jabber.org/protocol/pubsub#owner'> 1640 - <default/> 1641 - </pubsub> 1642 - </iq> 1643 + Non-overridden default yields unsupported error. 1644 """ 1645 1646 def cb(result): 1647 self.assertEquals('feature-not-implemented', result.condition) 1648 self.assertEquals('unsupported', result.appCondition.name) 1649 self.assertEquals(NS_PUBSUB_ERRORS, result.appCondition.uri) 1650 - self.assertEquals('retrieve-default', result.appCondition['feature']) 1651 + self.assertEquals('retrieve-default', 1652 + result.appCondition['feature']) 1653 1654 - d = self.handleRequest(xml) 1655 + d = self.resource.default(pubsub.PubSubRequest()) 1656 self.assertFailure(d, error.StanzaError) 1657 d.addCallback(cb) 1658 return d 1659 1660 1661 - def test_getConfiguration(self): 1662 + def test_configureGet(self): 1663 """ 1664 - Non-overridden L{PubSubService.getConfiguration} yields unsupported 1665 + Non-overridden configureGet yields unsupported 1666 error. 1667 """ 1668 1669 - xml = """ 1670 - <iq type='get' to='pubsub.example.org' 1671 - from='user@example.org'> 1672 - <pubsub xmlns='http://jabber.org/protocol/pubsub#owner'> 1673 - <configure/> 1674 - </pubsub> 1675 - </iq> 1676 - """ 1677 - 1678 def cb(result): 1679 self.assertEquals('feature-not-implemented', result.condition) 1680 self.assertEquals('unsupported', result.appCondition.name) 1681 self.assertEquals(NS_PUBSUB_ERRORS, result.appCondition.uri) 1682 self.assertEquals('config-node', result.appCondition['feature']) 1683 1684 - d = self.handleRequest(xml) 1685 + d = self.resource.configureGet(pubsub.PubSubRequest()) 1686 self.assertFailure(d, error.StanzaError) 1687 d.addCallback(cb) 1688 return d 1689 1690 1691 - def test_setConfiguration(self): 1692 + def test_configureSet(self): 1693 """ 1694 - Non-overridden L{PubSubService.setConfiguration} yields unsupported 1695 - error. 1696 - """ 1697 - 1698 - xml = """ 1699 - <iq type='set' to='pubsub.example.org' 1700 - from='user@example.org'> 1701 - <pubsub xmlns='http://jabber.org/protocol/pubsub#owner'> 1702 - <configure node='test'> 1703 - <x xmlns='jabber:x:data' type='submit'> 1704 - <field var='FORM_TYPE' type='hidden'> 1705 - <value>http://jabber.org/protocol/pubsub#node_config</value> 1706 - </field> 1707 - <field var='pubsub#deliver_payloads'><value>0</value></field> 1708 - <field var='pubsub#persist_items'><value>1</value></field> 1709 - </x> 1710 - </configure> 1711 - </pubsub> 1712 - </iq> 1713 + Non-overridden configureSet yields unsupported error. 1714 """ 1715 1716 def cb(result): 1717 @@ -2452,7 +2495,7 @@ 1718 self.assertEquals(NS_PUBSUB_ERRORS, result.appCondition.uri) 1719 self.assertEquals('config-node', result.appCondition['feature']) 1720 1721 - d = self.handleRequest(xml) 1722 + d = self.resource.configureSet(pubsub.PubSubRequest()) 1723 self.assertFailure(d, error.StanzaError) 1724 d.addCallback(cb) 1725 return d 1726 @@ -2460,15 +2503,7 @@ 1727 1728 def test_items(self): 1729 """ 1730 - Non-overridden L{PubSubService.items} yields unsupported error. 1731 - """ 1732 - xml = """ 1733 - <iq type='get' to='pubsub.example.org' 1734 - from='user@example.org'> 1735 - <pubsub xmlns='http://jabber.org/protocol/pubsub'> 1736 - <items node='test'/> 1737 - </pubsub> 1738 - </iq> 1739 + Non-overridden items yields unsupported error. 1740 """ 1741 1742 def cb(result): 1743 @@ -2477,7 +2512,7 @@ 1744 self.assertEquals(NS_PUBSUB_ERRORS, result.appCondition.uri) 1745 self.assertEquals('retrieve-items', result.appCondition['feature']) 1746 1747 - d = self.handleRequest(xml) 1748 + d = self.resource.items(pubsub.PubSubRequest()) 1749 self.assertFailure(d, error.StanzaError) 1750 d.addCallback(cb) 1751 return d 1752 @@ -2485,18 +2520,7 @@ 1753 1754 def test_retract(self): 1755 """ 1756 - Non-overridden L{PubSubService.retract} yields unsupported error. 1757 - """ 1758 - xml = """ 1759 - <iq type='set' to='pubsub.example.org' 1760 - from='user@example.org'> 1761 - <pubsub xmlns='http://jabber.org/protocol/pubsub'> 1762 - <retract node='test'> 1763 - <item id='item1'/> 1764 - <item id='item2'/> 1765 - </retract> 1766 - </pubsub> 1767 - </iq> 1768 + Non-overridden retract yields unsupported error. 1769 """ 1770 1771 def cb(result): 1772 @@ -2505,7 +2529,7 @@ 1773 self.assertEquals(NS_PUBSUB_ERRORS, result.appCondition.uri) 1774 self.assertEquals('retract-items', result.appCondition['feature']) 1775 1776 - d = self.handleRequest(xml) 1777 + d = self.resource.retract(pubsub.PubSubRequest()) 1778 self.assertFailure(d, error.StanzaError) 1779 d.addCallback(cb) 1780 return d 1781 @@ -2513,15 +2537,7 @@ 1782 1783 def test_purge(self): 1784 """ 1785 - Non-overridden L{PubSubService.purge} yields unsupported error. 1786 - """ 1787 - xml = """ 1788 - <iq type='set' to='pubsub.example.org' 1789 - from='user@example.org'> 1790 - <pubsub xmlns='http://jabber.org/protocol/pubsub#owner'> 1791 - <purge node='test'/> 1792 - </pubsub> 1793 - </iq> 1794 + Non-overridden purge yields unsupported error. 1795 """ 1796 1797 def cb(result): 1798 @@ -2530,7 +2546,7 @@ 1799 self.assertEquals(NS_PUBSUB_ERRORS, result.appCondition.uri) 1800 self.assertEquals('purge-nodes', result.appCondition['feature']) 1801 1802 - d = self.handleRequest(xml) 1803 + d = self.resource.purge(pubsub.PubSubRequest()) 1804 self.assertFailure(d, error.StanzaError) 1805 d.addCallback(cb) 1806 return d 1807 @@ -2538,15 +2554,7 @@ 1808 1809 def test_delete(self): 1810 """ 1811 - Non-overridden L{PubSubService.delete} yields unsupported error. 1812 - """ 1813 - xml = """ 1814 - <iq type='set' to='pubsub.example.org' 1815 - from='user@example.org'> 1816 - <pubsub xmlns='http://jabber.org/protocol/pubsub#owner'> 1817 - <delete node='test'/> 1818 - </pubsub> 1819 - </iq> 1820 + Non-overridden delete yields unsupported error. 1821 """ 1822 1823 def cb(result): 1824 @@ -2555,7 +2563,7 @@ 1825 self.assertEquals(NS_PUBSUB_ERRORS, result.appCondition.uri) 1826 self.assertEquals('delete-nodes', result.appCondition['feature']) 1827 1828 - d = self.handleRequest(xml) 1829 + d = self.resource.delete(pubsub.PubSubRequest()) 1830 self.assertFailure(d, error.StanzaError) 1831 d.addCallback(cb) 1832 return d
Note: See TracChangeset
for help on using the changeset viewer.