source: ralphm-patches/pubsub_resource.patch @ 5:231bc3e8b810

Last change on this file since 5:231bc3e8b810 was 5:231bc3e8b810, checked in by Ralph Meijer <ralphm@…>, 12 years ago

A gazillion changes.

File size: 59.4 KB
  • wokkel/iwokkel.py

    diff -r 2ea6196efcdc wokkel/iwokkel.py
    a b  
    297297        """
    298298
    299299
    300     def publish(request):
     300class IPubSubResource(Interface):
     301
     302    def locateResource(request):
    301303        """
    302         Called when a publish request has been received.
     304        Locate a resource that will handle the request.
    303305
    304306        @param request: The publish-subscribe request.
    305307        @type request: L{wokkel.pubsub.PubSubRequest}
    306         @return: deferred that fires on success.
     308        """
     309
     310
     311    def getInfo(requestor, service, nodeIdentifier):
     312        """
     313        Get node type and meta data.
     314
     315        @param requestor: The entity the request originated from.
     316        @type requestor: L{jid.JID}
     317        @param service: The publish-subscribe service entity.
     318        @type service: L{jid.JID}
     319        @param nodeIdentifier: Identifier of the node to request the info for.
     320        @type nodeIdentifier: L{unicode}
     321        @return: A deferred that fires with a dictionary. If not empty,
     322                 it must have the keys C{'type'} and C{'meta-data'} to keep
     323                 respectively the node type and a dictionary with the meta
     324                 data for that node.
    307325        @rtype: L{defer.Deferred}
    308326        """
    309327
    310328
    311     def subscribe(request):
     329    def getNodes(requestor, service, nodeIdentifier):
    312330        """
    313         Called when a subscribe request has been received.
     331        Get all nodes contained by this node.
    314332
    315         @param request: The publish-subscribe request.
    316         @type request: L{wokkel.pubsub.PubSubRequest}
    317         @return: A deferred that fires with a
    318                  L{Subscription<wokkel.pubsub.Subscription>}.
    319         @rtype: L{defer.Deferred}
    320         """
    321 
    322 
    323     def unsubscribe(request):
    324         """
    325         Called when a subscribe request has been received.
    326 
    327         @param request: The publish-subscribe request.
    328         @type request: L{wokkel.pubsub.PubSubRequest}
    329         @return: A deferred that fires with C{None} when unsubscription has
    330                  succeeded.
    331         @rtype: L{defer.Deferred}
    332         """
    333 
    334 
    335     def subscriptions(request):
    336         """
    337         Called when a subscriptions retrieval request has been received.
    338 
    339         @param request: The publish-subscribe request.
    340         @type request: L{wokkel.pubsub.PubSubRequest}
    341         @return: A deferred that fires with a C{list} of subscriptions as
    342                  L{Subscription<wokkel.pubsub.Subscription>}.
    343         @rtype: L{defer.Deferred}
    344         """
    345 
    346 
    347     def affiliations(request):
    348         """
    349         Called when a affiliations retrieval request has been received.
    350 
    351         @param request: The publish-subscribe request.
    352         @type request: L{wokkel.pubsub.PubSubRequest}
    353         @return: A deferred that fires with a C{list} of affiliations as
    354                  C{tuple}s of (node identifier as C{unicode}, affiliation state
    355                  as C{str}). The affiliation can be C{'owner'}, C{'publisher'},
    356                  or C{'outcast'}.
    357         @rtype: L{defer.Deferred}
    358         """
    359 
    360 
    361     def create(request):
    362         """
    363         Called when a node creation request has been received.
    364 
    365         @param request: The publish-subscribe request.
    366         @type request: L{wokkel.pubsub.PubSubRequest}
    367         @return: A deferred that fires with a C{unicode} that represents
    368                  the identifier of the new node.
     333        @param requestor: The entity the request originated from.
     334        @type requestor: L{jid.JID}
     335        @param service: The publish-subscribe service entity.
     336        @type service: L{jid.JID}
     337        @param nodeIdentifier: Identifier of the node to request the childs for.
     338        @type nodeIdentifier: L{unicode}
     339        @return: A deferred that fires with a list of child node identifiers.
    369340        @rtype: L{defer.Deferred}
    370341        """
    371342
     
    406377        """
    407378
    408379
    409     def getDefaultConfiguration(request):
     380    def publish(request):
     381        """
     382        Called when a publish request has been received.
     383
     384        @param request: The publish-subscribe request.
     385        @type request: L{wokkel.pubsub.PubSubRequest}
     386        @return: deferred that fires on success.
     387        @rtype: L{defer.Deferred}
     388        """
     389
     390
     391    def subscribe(request):
     392        """
     393        Called when a subscribe request has been received.
     394
     395        @param request: The publish-subscribe request.
     396        @type request: L{wokkel.pubsub.PubSubRequest}
     397        @return: A deferred that fires with a
     398                 L{Subscription<wokkel.pubsub.Subscription>}.
     399        @rtype: L{defer.Deferred}
     400        """
     401
     402
     403    def unsubscribe(request):
     404        """
     405        Called when a subscribe request has been received.
     406
     407        @param request: The publish-subscribe request.
     408        @type request: L{wokkel.pubsub.PubSubRequest}
     409        @return: A deferred that fires with C{None} when unsubscription has
     410                 succeeded.
     411        @rtype: L{defer.Deferred}
     412        """
     413
     414
     415    def subscriptions(request):
     416        """
     417        Called when a subscriptions retrieval request has been received.
     418
     419        @param request: The publish-subscribe request.
     420        @type request: L{wokkel.pubsub.PubSubRequest}
     421        @return: A deferred that fires with a C{list} of subscriptions as
     422                 L{Subscription<wokkel.pubsub.Subscription>}.
     423        @rtype: L{defer.Deferred}
     424        """
     425
     426
     427    def affiliations(request):
     428        """
     429        Called when a affiliations retrieval request has been received.
     430
     431        @param request: The publish-subscribe request.
     432        @type request: L{wokkel.pubsub.PubSubRequest}
     433        @return: A deferred that fires with a C{list} of affiliations as
     434                 C{tuple}s of (node identifier as C{unicode}, affiliation state
     435                 as C{str}). The affiliation can be C{'owner'}, C{'publisher'},
     436                 or C{'outcast'}.
     437        @rtype: L{defer.Deferred}
     438        """
     439
     440
     441    def create(request):
     442        """
     443        Called when a node creation request has been received.
     444
     445        @param request: The publish-subscribe request.
     446        @type request: L{wokkel.pubsub.PubSubRequest}
     447        @return: A deferred that fires with a C{unicode} that represents
     448                 the identifier of the new node.
     449        @rtype: L{defer.Deferred}
     450        """
     451
     452
     453    def default(request):
    410454        """
    411455        Called when a default node configuration request has been received.
    412456
     
    420464        """
    421465
    422466
    423     def getConfiguration(request):
     467    def configureGet(request):
    424468        """
    425469        Called when a node configuration retrieval request has been received.
    426470
     
    433477        """
    434478
    435479
    436     def setConfiguration(request):
     480    def configureSet(request):
    437481        """
    438482        Called when a node configuration change request has been received.
    439483
  • wokkel/pubsub.py

    diff -r 2ea6196efcdc wokkel/pubsub.py
    a b  
    1313from zope.interface import implements
    1414
    1515from twisted.internet import defer
     16from twisted.python import log
    1617from twisted.words.protocols.jabber import jid, error, xmlstream
    1718from twisted.words.xish import domish
    1819
    1920from wokkel import disco, data_form, generic, shim
    2021from wokkel.subprotocols import IQHandlerMixin, XMPPHandler
    21 from wokkel.iwokkel import IPubSubClient, IPubSubService
     22from wokkel.iwokkel import IPubSubClient, IPubSubService, IPubSubResource
    2223
    2324# Iq get and set XPath queries
    2425IQ_GET = '/iq[@type="get"]'
     
    8485
    8586class Unsupported(PubSubError):
    8687    def __init__(self, feature, text=None):
     88        self.feature = feature
    8789        PubSubError.__init__(self, 'feature-not-implemented',
    8890                                   'unsupported',
    8991                                   feature,
    9092                                   text)
    9193
     94    def __str__(self):
     95        message = PubSubError.__str__(self)
     96        message += ', feature %r' % self.feature
     97        return message
    9298
    9399
    94100class Subscription(object):
     
    235241        'retract': ['node', 'itemIdentifiers'],
    236242        'purge': ['node'],
    237243        'delete': ['node'],
    238         'affiliationsGet': [],
     244        'affiliationsGet': ['nodeOrEmpty'],
    239245        'affiliationsSet': [],
    240         'subscriptionsGet': [],
     246        'subscriptionsGet': ['nodeOrEmpty'],
    241247        'subscriptionsSet': [],
    242248    }
    243249
     
    806812            '/*': '_onPubSubRequest',
    807813            }
    808814
     815    hideNodes = False
    809816
    810     def __init__(self):
    811         self.discoIdentity = {'category': 'pubsub',
    812                               'type': 'generic',
    813                               'name': 'Generic Publish-Subscribe Service'}
    814 
    815         self.pubSubFeatures = []
     817    def __init__(self, resource):
     818        self.resource = resource
    816819
    817820
    818821    def connectionMade(self):
     
    820823
    821824
    822825    def getDiscoInfo(self, requestor, target, nodeIdentifier):
    823         info = []
    824 
    825         if not nodeIdentifier:
    826             category, idType, name = self.discoIdentity
    827             info.append(disco.DiscoIdentity(category, idType, name))
    828 
    829             info.append(disco.DiscoFeature(disco.NS_DISCO_ITEMS))
    830             info.extend([disco.DiscoFeature("%s#%s" % (NS_PUBSUB, feature))
    831                          for feature in self.pubSubFeatures])
    832 
    833         def toInfo(nodeInfo):
     826        def toInfo(nodeInfo, info):
    834827            if not nodeInfo:
    835                 return
     828                return info
    836829
    837830            (nodeType, metaData) = nodeInfo['type'], nodeInfo['meta-data']
    838831            info.append(disco.DiscoIdentity('pubsub', nodeType))
     
    852845
    853846                info.append(form.toElement())
    854847
    855         d = self.getNodeInfo(requestor, target, nodeIdentifier or '')
    856         d.addCallback(toInfo)
    857         d.addBoth(lambda result: info)
     848            return info
     849
     850        info = []
     851
     852        request = PubSubRequest('discoInfo')
     853        resource = self.resource.locateResource(request)
     854
     855        if not nodeIdentifier:
     856            info.append(resource.discoIdentity)
     857            info.append(disco.DiscoFeature(disco.NS_DISCO_ITEMS))
     858            info.extend([disco.DiscoFeature("%s#%s" % (NS_PUBSUB, feature))
     859                         for feature in resource.features])
     860
     861        d = resource.getInfo(requestor, target, nodeIdentifier or '')
     862        d.addCallback(toInfo, info)
     863        d.addErrback(log.err)
    858864        return d
    859865
    860866
    861867    def getDiscoItems(self, requestor, target, nodeIdentifier):
    862         if nodeIdentifier or self.hideNodes:
     868        request = PubSubRequest('discoInfo')
     869        resource = self.resource.locateResource(request)
     870
     871        if self.hideNodes:
    863872            return defer.succeed([])
    864873
    865         d = self.getNodes(requestor, target)
     874        d = resource.getNodes(requestor, target, nodeIdentifier)
    866875        d.addCallback(lambda nodes: [disco.DiscoItem(target, node)
    867876                                     for node in nodes])
    868877        return d
     
    870879
    871880    def _onPubSubRequest(self, iq):
    872881        request = PubSubRequest.fromElement(iq)
    873         handler = getattr(self, '_on_%s' % request.verb)
    874         return handler(request)
     882        resource = self.resource.locateResource(request)
    875883
     884        # Preprocess the request, knowing the handling resource
     885        try:
     886            preProcessor = getattr(self, '_preProcess_%s' % request.verb)
     887        except AttributeError:
     888            pass
     889        else:
     890            request = preProcessor(resource, request)
     891            if request is None:
     892                return defer.succeed(None)
    876893
    877     def _on_publish(self, request):
    878         return self.publish(request)
     894        # Process the request itself,
     895        try:
     896            handler = getattr(resource, request.verb)
     897        except AttributeError:
     898            # fix lookup feature
     899            text = "Request verb: %s" % request.verb
     900            return defer.fail(Unsupported('', text))
    879901
     902        d = handler(request)
    880903
    881     def _on_subscribe(self, request):
     904        # If needed, translate the result into a response
     905        try:
     906            cb = getattr(self, '_toResponse_%s' % request.verb)
     907        except AttributeError:
     908            pass
     909        else:
     910            d.addCallback(cb, resource, request)
    882911
    883         def toResponse(result):
    884             response = domish.Element((NS_PUBSUB, "pubsub"))
    885             subscription = response.addElement("subscription")
    886             if result.nodeIdentifier:
    887                 subscription["node"] = result.nodeIdentifier
    888             subscription["jid"] = result.subscriber.full()
    889             subscription["subscription"] = result.state
    890             return response
    891 
    892         d = self.subscribe(request)
    893         d.addCallback(toResponse)
    894912        return d
    895913
    896914
    897     def _on_unsubscribe(self, request):
    898         return self.unsubscribe(request)
     915    def _toResponse_subscribe(self, result, resource, request):
     916        response = domish.Element((NS_PUBSUB, "pubsub"))
     917        subscription = response.addElement("subscription")
     918        if result.nodeIdentifier:
     919            subscription["node"] = result.nodeIdentifier
     920        subscription["jid"] = result.subscriber.full()
     921        subscription["subscription"] = result.state
     922        return response
    899923
    900924
    901     def _on_optionsGet(self, request):
    902         raise Unsupported('subscription-options')
     925    def _toResponse_subscriptions(self, result, resource, request):
     926        response = domish.Element((NS_PUBSUB, 'pubsub'))
     927        subscriptions = response.addElement('subscriptions')
     928        for subscription in result:
     929            item = subscriptions.addElement('subscription')
     930            item['node'] = subscription.nodeIdentifier
     931            item['jid'] = subscription.subscriber.full()
     932            item['subscription'] = subscription.state
     933        return response
    903934
    904935
    905     def _on_optionsSet(self, request):
    906         raise Unsupported('subscription-options')
     936    def _toResponse_affiliations(self, result, resource, request):
     937        response = domish.Element((NS_PUBSUB, 'pubsub'))
     938        affiliations = response.addElement('affiliations')
    907939
     940        for nodeIdentifier, affiliation in result:
     941            item = affiliations.addElement('affiliation')
     942            item['node'] = nodeIdentifier
     943            item['affiliation'] = affiliation
    908944
    909     def _on_subscriptions(self, request):
     945        return response
    910946
    911         def toResponse(result):
     947
     948    def _toResponse_create(self, result, resource, request):
     949        if not request.nodeIdentifier or request.nodeIdentifier != result:
    912950            response = domish.Element((NS_PUBSUB, 'pubsub'))
    913             subscriptions = response.addElement('subscriptions')
    914             for subscription in result:
    915                 item = subscriptions.addElement('subscription')
    916                 item['node'] = subscription.nodeIdentifier
    917                 item['jid'] = subscription.subscriber.full()
    918                 item['subscription'] = subscription.state
     951            create = response.addElement('create')
     952            create['node'] = result
    919953            return response
    920 
    921         d = self.subscriptions(request)
    922         d.addCallback(toResponse)
    923         return d
    924 
    925 
    926     def _on_affiliations(self, request):
    927 
    928         def toResponse(result):
    929             response = domish.Element((NS_PUBSUB, 'pubsub'))
    930             affiliations = response.addElement('affiliations')
    931 
    932             for nodeIdentifier, affiliation in result:
    933                 item = affiliations.addElement('affiliation')
    934                 item['node'] = nodeIdentifier
    935                 item['affiliation'] = affiliation
    936 
    937             return response
    938 
    939         d = self.affiliations(request)
    940         d.addCallback(toResponse)
    941         return d
    942 
    943 
    944     def _on_create(self, request):
    945 
    946         def toResponse(result):
    947             if not request.nodeIdentifier or request.nodeIdentifier != result:
    948                 response = domish.Element((NS_PUBSUB, 'pubsub'))
    949                 create = response.addElement('create')
    950                 create['node'] = result
    951                 return response
    952             else:
    953                 return None
    954 
    955         d = self.create(request)
    956         d.addCallback(toResponse)
    957         return d
     954        else:
     955            return None
    958956
    959957
    960958    def _makeFields(self, options, values):
     
    973971        return fields
    974972
    975973
    976     def _formFromConfiguration(self, values):
    977         options = self.getConfigurationOptions()
     974    def _formFromConfiguration(self, resource, values):
     975        options = resource.getConfigurationOptions()
    978976        fields = self._makeFields(options, values)
    979977        form = data_form.Form(formType="form",
    980978                              formNamespace=NS_PUBSUB_NODE_CONFIG,
     
    983981        return form
    984982
    985983
    986     def _checkConfiguration(self, values):
    987         options = self.getConfigurationOptions()
     984    def _checkConfiguration(self, resource, values):
     985        options = resource.getConfigurationOptions()
    988986        processedValues = {}
    989987
    990988        for key, value in values.iteritems():
     
    10081006        return processedValues
    10091007
    10101008
    1011     def _on_default(self, request):
     1009    def _preProcess_default(self, resource, request):
     1010        if request.nodeType not in ('leaf', 'collection'):
     1011            raise error.StanzaError('not-acceptable')
     1012        else:
     1013            return request
    10121014
    1013         def toResponse(options):
    1014             response = domish.Element((NS_PUBSUB_OWNER, "pubsub"))
    1015             default = response.addElement("default")
    1016             default.addChild(self._formFromConfiguration(options).toElement())
    1017             return response
    10181015
    1019         if request.nodeType not in ('leaf', 'collection'):
    1020             return defer.fail(error.StanzaError('not-acceptable'))
     1016    def _toResponse_default(self, options, resource, request):
     1017        response = domish.Element((NS_PUBSUB_OWNER, "pubsub"))
     1018        default = response.addElement("default")
     1019        form = self._formFromConfiguration(resource, options)
     1020        default.addChild(form.toElement())
     1021        return response
    10211022
    1022         d = self.getDefaultConfiguration(request)
    1023         d.addCallback(toResponse)
    1024         return d
    10251023
     1024    def _toResponse_configureGet(self, options, resource, request):
     1025        response = domish.Element((NS_PUBSUB_OWNER, "pubsub"))
     1026        configure = response.addElement("configure")
     1027        form = self._formFromConfiguration(resource, options)
     1028        configure.addChild(form.toElement())
    10261029
    1027     def _on_configureGet(self, request):
    1028         def toResponse(options):
    1029             response = domish.Element((NS_PUBSUB_OWNER, "pubsub"))
    1030             configure = response.addElement("configure")
    1031             form = self._formFromConfiguration(options)
    1032             configure.addChild(form.toElement())
     1030        if request.nodeIdentifier:
     1031            configure["node"] = request.nodeIdentifier
    10331032
    1034             if request.nodeIdentifier:
    1035                 configure["node"] = request.nodeIdentifier
     1033        return response
    10361034
    1037             return response
    10381035
    1039         d = self.getConfiguration(request)
    1040         d.addCallback(toResponse)
    1041         return d
    1042 
    1043 
    1044     def _on_configureSet(self, request):
     1036    def _preProcess_configureSet(self, resource, request):
    10451037        if request.options:
    1046             request.options = self._checkConfiguration(request.options)
    1047             return self.setConfiguration(request)
     1038            request.options = self._checkConfiguration(resource,
     1039                                                       request.options)
     1040            return request
    10481041        else:
    10491042            return None
    10501043
    10511044
     1045    def _toResponse_items(self, result, resource, request):
     1046        response = domish.Element((NS_PUBSUB, 'pubsub'))
     1047        items = response.addElement('items')
     1048        items["node"] = request.nodeIdentifier
    10521049
    1053     def _on_items(self, request):
     1050        for item in result:
     1051            items.addChild(item)
    10541052
    1055         def toResponse(result):
    1056             response = domish.Element((NS_PUBSUB, 'pubsub'))
    1057             items = response.addElement('items')
    1058             items["node"] = request.nodeIdentifier
     1053        return response
    10591054
    1060             for item in result:
    1061                 items.addChild(item)
    1062 
    1063             return response
    1064 
    1065         d = self.items(request)
    1066         d.addCallback(toResponse)
    1067         return d
    1068 
    1069 
    1070     def _on_retract(self, request):
    1071         return self.retract(request)
    1072 
    1073 
    1074     def _on_purge(self, request):
    1075         return self.purge(request)
    1076 
    1077 
    1078     def _on_delete(self, request):
    1079         return self.delete(request)
    1080 
    1081 
    1082     def _on_affiliationsGet(self, iq):
    1083         raise Unsupported('modify-affiliations')
    1084 
    1085 
    1086     def _on_affiliationsSet(self, iq):
    1087         raise Unsupported('modify-affiliations')
    1088 
    1089 
    1090     def _on_subscriptionsGet(self, iq):
    1091         raise Unsupported('manage-subscriptions')
    1092 
    1093 
    1094     def _on_subscriptionsSet(self, iq):
    1095         raise Unsupported('manage-subscriptions')
    1096 
    1097     # public methods
    10981055
    10991056    def _createNotification(self, eventType, service, nodeIdentifier,
    11001057                                  subscriber, subscriptions=None):
     
    11181075
    11191076        return message
    11201077
     1078    # public methods
     1079
    11211080    def notifyPublish(self, service, nodeIdentifier, notifications):
    11221081        for subscriber, subscriptions, items in notifications:
    11231082            message = self._createNotification('items', service,
     
    11391098            self.send(message)
    11401099
    11411100
    1142     def getNodeInfo(self, requestor, service, nodeIdentifier):
    1143         return None
    11441101
     1102class PubSubResource(object):
    11451103
    1146     def getNodes(self, requestor, service):
    1147         return []
     1104    implements(IPubSubResource)
    11481105
     1106    features = []
     1107    discoIdentity = disco.DiscoIdentity('pubsub',
     1108                                        'service',
     1109                                        'Publish-Subscribe Service')
    11491110
    1150     def publish(self, request):
    1151         raise Unsupported('publish')
    11521111
     1112    def locateResource(self, request):
     1113        return self
    11531114
    1154     def subscribe(self, request):
    1155         raise Unsupported('subscribe')
    11561115
     1116    def getInfo(self, requestor, service, nodeIdentifier):
     1117        return defer.succeed(None)
    11571118
    1158     def unsubscribe(self, request):
    1159         raise Unsupported('subscribe')
    11601119
    1161 
    1162     def subscriptions(self, request):
    1163         raise Unsupported('retrieve-subscriptions')
    1164 
    1165 
    1166     def affiliations(self, request):
    1167         raise Unsupported('retrieve-affiliations')
    1168 
    1169 
    1170     def create(self, request):
    1171         raise Unsupported('create-nodes')
     1120    def getNodes(self, requestor, service, nodeIdentifier):
     1121        return defer.succeed([])
    11721122
    11731123
    11741124    def getConfigurationOptions(self):
    11751125        return {}
    11761126
    11771127
    1178     def getDefaultConfiguration(self, request):
    1179         raise Unsupported('retrieve-default')
     1128    def publish(self, request):
     1129        return defer.fail(Unsupported('publish'))
    11801130
    11811131
    1182     def getConfiguration(self, request):
    1183         raise Unsupported('config-node')
     1132    def subscribe(self, request):
     1133        return defer.fail(Unsupported('subscribe'))
    11841134
    11851135
    1186     def setConfiguration(self, request):
    1187         raise Unsupported('config-node')
     1136    def unsubscribe(self, request):
     1137        return defer.fail(Unsupported('subscribe'))
     1138
     1139
     1140    def subscriptions(self, request):
     1141        return defer.fail(Unsupported('retrieve-subscriptions'))
     1142
     1143
     1144    def affiliations(self, request):
     1145        return defer.fail(Unsupported('retrieve-affiliations'))
     1146
     1147
     1148    def create(self, request):
     1149        return defer.fail(Unsupported('create-nodes'))
     1150
     1151
     1152    def default(self, request):
     1153        return defer.fail(Unsupported('retrieve-default'))
     1154
     1155
     1156    def configureGet(self, request):
     1157        return defer.fail(Unsupported('config-node'))
     1158
     1159
     1160    def configureSet(self, request):
     1161        return defer.fail(Unsupported('config-node'))
    11881162
    11891163
    11901164    def items(self, request):
    1191         raise Unsupported('retrieve-items')
     1165        return defer.fail(Unsupported('retrieve-items'))
    11921166
    11931167
    11941168    def retract(self, request):
    1195         raise Unsupported('retract-items')
     1169        return defer.fail(Unsupported('retract-items'))
    11961170
    11971171
    11981172    def purge(self, request):
    1199         raise Unsupported('purge-nodes')
     1173        return defer.fail(Unsupported('purge-nodes'))
    12001174
    12011175
    12021176    def delete(self, request):
    1203         raise Unsupported('delete-nodes')
     1177        return defer.fail(Unsupported('delete-nodes'))
     1178
     1179
     1180    def affiliationsGet(self, request):
     1181        return defer.fail(Unsupported('modify-affiliations'))
     1182
     1183
     1184    def affiliationsSet(self, request):
     1185        return defer.fail(Unsupported('modify-affiliations'))
     1186
     1187
     1188    def subscriptionsGet(self, request):
     1189        return defer.fail(Unsupported('manage-subscriptions'))
     1190
     1191
     1192    def subscriptionsSet(self, request):
     1193        return defer.fail(Unsupported('manage-subscriptions'))
  • wokkel/test/test_pubsub.py

    diff -r 2ea6196efcdc wokkel/test/test_pubsub.py
    a b  
    1313from twisted.words.protocols.jabber import error
    1414from twisted.words.protocols.jabber.jid import JID
    1515
    16 from wokkel import data_form, iwokkel, pubsub, shim
     16from wokkel import data_form, disco, iwokkel, pubsub, shim
    1717from wokkel.generic import parseXml
    1818from wokkel.test.helpers import TestableRequestHandlerMixin, XmlStreamStub
    1919
     
    12251225
    12261226    def setUp(self):
    12271227        self.stub = XmlStreamStub()
    1228         self.service = pubsub.PubSubService()
     1228        self.resource = pubsub.PubSubResource()
     1229        self.service = pubsub.PubSubService(self.resource)
    12291230        self.service.send = self.stub.xmlstream.send
    12301231
    12311232    def test_interface(self):
     
    12631264        Test getDiscoInfo calls getNodeInfo and returns some minimal info.
    12641265        """
    12651266        def cb(info):
    1266             self.assertEqual(2, len(info))
     1267            discoInfo = disco.DiscoInfo()
     1268            for item in info:
     1269                discoInfo.append(item)
     1270            self.assertIn(('pubsub', 'service'), discoInfo.identities)
     1271            self.assertIn(disco.NS_DISCO_ITEMS, discoInfo.features)
    12671272
    1268         def getNodeInfo(requestor, target, nodeIdentifier):
    1269             return defer.succeed(None)
    1270 
    1271         self.service.getNodeInfo = getNodeInfo
    12721273        d = self.service.getDiscoInfo(JID('user@example.org/home'),
    12731274                                      JID('pubsub.example.org'), '')
    12741275        d.addCallback(cb)
    12751276        return d
    12761277
    12771278
    1278     def test_onPublish(self):
     1279    def test_getDiscoInfoNodeType(self):
     1280        """
     1281        Test getDiscoInfo calls getNodeInfo and returns some minimal info.
     1282        """
     1283        def cb(info):
     1284            discoInfo = disco.DiscoInfo()
     1285            for item in info:
     1286                discoInfo.append(item)
     1287            self.assertIn(('pubsub', 'collection'), discoInfo.identities)
     1288
     1289        def getInfo(requestor, target, nodeIdentifier):
     1290            return defer.succeed({'type': 'collection',
     1291                                  'meta-data': {}})
     1292
     1293        self.resource.getInfo = getInfo
     1294        d = self.service.getDiscoInfo(JID('user@example.org/home'),
     1295                                      JID('pubsub.example.org'), '')
     1296        d.addCallback(cb)
     1297        return d
     1298
     1299
     1300    def test_getDiscoInfoResourceFeatures(self):
     1301        """
     1302        Test getDiscoInfo calls getNodeInfo and returns some minimal info.
     1303        """
     1304        def cb(info):
     1305            discoInfo = disco.DiscoInfo()
     1306            for item in info:
     1307                discoInfo.append(item)
     1308            self.assertIn('http://jabber.org/protocol/pubsub#publish',
     1309                          discoInfo.features)
     1310
     1311        self.resource.features = ['publish']
     1312        d = self.service.getDiscoInfo(JID('user@example.org/home'),
     1313                                      JID('pubsub.example.org'), '')
     1314        d.addCallback(cb)
     1315        return d
     1316
     1317
     1318    def test_getDiscoItemsRoot(self):
     1319        """
     1320        Test getDiscoItems on the root node.
     1321        """
     1322        def getNodes(requestor, service, nodeIdentifier):
     1323            return defer.succeed(['node1', 'node2'])
     1324
     1325        def cb(items):
     1326            self.assertEqual(2, len(items))
     1327            item1, item2 = items
     1328
     1329            self.assertEqual(JID('pubsub.example.org'), item1.entity)
     1330            self.assertEqual('node1', item1.nodeIdentifier)
     1331
     1332            self.assertEqual(JID('pubsub.example.org'), item2.entity)
     1333            self.assertEqual('node2', item2.nodeIdentifier)
     1334
     1335        self.resource.getNodes = getNodes
     1336        d = self.service.getDiscoItems(JID('user@example.org/home'),
     1337                                       JID('pubsub.example.org'),
     1338                                       '')
     1339        d.addCallback(cb)
     1340        return d
     1341
     1342
     1343    def test_getDiscoItemsRootHideNodes(self):
     1344        """
     1345        Test getDiscoItems on the root node.
     1346        """
     1347        def getNodes(requestor, service, nodeIdentifier):
     1348            raise Exception("Unexpected call to getNodes")
     1349
     1350        def cb(items):
     1351            self.assertEqual([], items)
     1352
     1353        self.service.hideNodes = True
     1354        self.resource.getNodes = getNodes
     1355        d = self.service.getDiscoItems(JID('user@example.org/home'),
     1356                                       JID('pubsub.example.org'),
     1357                                       '')
     1358        d.addCallback(cb)
     1359        return d
     1360
     1361
     1362    def test_getDiscoItemsNonRoot(self):
     1363        """
     1364        Test getDiscoItems on a non-root node.
     1365        """
     1366        def getNodes(requestor, service, nodeIdentifier):
     1367            return defer.succeed(['node1', 'node2'])
     1368
     1369        def cb(items):
     1370            self.assertEqual(2, len(items))
     1371
     1372        self.resource.getNodes = getNodes
     1373        d = self.service.getDiscoItems(JID('user@example.org/home'),
     1374                                       JID('pubsub.example.org'),
     1375                                       'test')
     1376        d.addCallback(cb)
     1377        return d
     1378
     1379
     1380    def test_on_publish(self):
    12791381        """
    12801382        A publish request should result in L{PubSubService.publish} being
    12811383        called.
     
    12931395        def publish(request):
    12941396            return defer.succeed(None)
    12951397
    1296         self.service.publish = publish
    1297         verify.verifyObject(iwokkel.IPubSubService, self.service)
     1398        self.resource.publish = publish
     1399        verify.verifyObject(iwokkel.IPubSubResource, self.resource)
    12981400        return self.handleRequest(xml)
    12991401
    13001402
    1301     def test_onSubscribe(self):
     1403    def test_on_subscribe(self):
    13021404        """
    13031405        A successful subscription should return the current subscription.
    13041406        """
     
    13261428            self.assertEqual('user@example.org/Home', subscription['jid'])
    13271429            self.assertEqual('subscribed', subscription['subscription'])
    13281430
    1329         self.service.subscribe = subscribe
    1330         verify.verifyObject(iwokkel.IPubSubService, self.service)
     1431        self.resource.subscribe = subscribe
     1432        verify.verifyObject(iwokkel.IPubSubResource, self.resource)
    13311433        d = self.handleRequest(xml)
    13321434        d.addCallback(cb)
    13331435        return d
    13341436
    13351437
    1336     def test_onSubscribeEmptyNode(self):
     1438    def test_on_subscribeEmptyNode(self):
    13371439        """
    13381440        A successful subscription on root node should return no node attribute.
    13391441        """
     
    13551457        def cb(element):
    13561458            self.assertFalse(element.subscription.hasAttribute('node'))
    13571459
    1358         self.service.subscribe = subscribe
    1359         verify.verifyObject(iwokkel.IPubSubService, self.service)
     1460        self.resource.subscribe = subscribe
     1461        verify.verifyObject(iwokkel.IPubSubResource, self.resource)
    13601462        d = self.handleRequest(xml)
    13611463        d.addCallback(cb)
    13621464        return d
    13631465
    13641466
    1365     def test_onUnsubscribe(self):
     1467    def test_on_unsubscribe(self):
    13661468        """
    13671469        A successful unsubscription should return an empty response.
    13681470        """
     
    13821484        def cb(element):
    13831485            self.assertIdentical(None, element)
    13841486
    1385         self.service.unsubscribe = unsubscribe
    1386         verify.verifyObject(iwokkel.IPubSubService, self.service)
     1487        self.resource.unsubscribe = unsubscribe
     1488        verify.verifyObject(iwokkel.IPubSubResource, self.resource)
    13871489        d = self.handleRequest(xml)
    13881490        d.addCallback(cb)
    13891491        return d
    13901492
    13911493
    1392     def test_onOptionsGet(self):
     1494    def test_on_optionsGet(self):
    13931495        """
    13941496        Getting subscription options is not supported.
    13951497        """
     
    14141516        return d
    14151517
    14161518
    1417     def test_onOptionsSet(self):
     1519    def test_on_optionsSet(self):
    14181520        """
    14191521        Setting subscription options is not supported.
    14201522        """
     
    14461548        return d
    14471549
    14481550
    1449     def test_onSubscriptions(self):
     1551    def test_on_subscriptions(self):
    14501552        """
    14511553        A subscriptions request should result in
    14521554        L{PubSubService.subscriptions} being called and the result prepared
     
    14621564        </iq>
    14631565        """
    14641566
     1567        def subscriptions(request):
     1568            subscription = pubsub.Subscription('test', JID('user@example.org'),
     1569                                               'subscribed')
     1570            return defer.succeed([subscription])
     1571
    14651572        def cb(element):
    14661573            self.assertEqual('pubsub', element.name)
    14671574            self.assertEqual(NS_PUBSUB, element.uri)
     
    14751582            self.assertEqual('test', subscription['node'])
    14761583            self.assertEqual('subscribed', subscription['subscription'])
    14771584
    1478 
    1479         def subscriptions(request):
    1480             subscription = pubsub.Subscription('test', JID('user@example.org'),
    1481                                                'subscribed')
    1482             return defer.succeed([subscription])
    1483 
    1484         self.service.subscriptions = subscriptions
    1485         verify.verifyObject(iwokkel.IPubSubService, self.service)
     1585        self.resource.subscriptions = subscriptions
     1586        verify.verifyObject(iwokkel.IPubSubResource, self.resource)
    14861587        d = self.handleRequest(xml)
    14871588        d.addCallback(cb)
    14881589        return d
    14891590
    14901591
    1491     def test_onAffiliations(self):
     1592    def test_on_affiliations(self):
    14921593        """
    14931594        A subscriptions request should result in
    14941595        L{PubSubService.affiliations} being called and the result prepared
     
    15041605        </iq>
    15051606        """
    15061607
     1608        def affiliations(request):
     1609            affiliation = ('test', 'owner')
     1610            return defer.succeed([affiliation])
     1611
    15071612        def cb(element):
    15081613            self.assertEqual('pubsub', element.name)
    15091614            self.assertEqual(NS_PUBSUB, element.uri)
     
    15161621            self.assertEqual('test', affiliation['node'])
    15171622            self.assertEqual('owner', affiliation['affiliation'])
    15181623
    1519 
    1520         def affiliations(request):
    1521             affiliation = ('test', 'owner')
    1522             return defer.succeed([affiliation])
    1523 
    1524         self.service.affiliations = affiliations
    1525         verify.verifyObject(iwokkel.IPubSubService, self.service)
     1624        self.resource.affiliations = affiliations
     1625        verify.verifyObject(iwokkel.IPubSubResource, self.resource)
    15261626        d = self.handleRequest(xml)
    15271627        d.addCallback(cb)
    15281628        return d
    15291629
    15301630
    1531     def test_onCreate(self):
     1631    def test_on_create(self):
    15321632        """
    15331633        Replies to create node requests don't return the created node.
    15341634        """
     
    15481648        def cb(element):
    15491649            self.assertIdentical(None, element)
    15501650
    1551         self.service.create = create
    1552         verify.verifyObject(iwokkel.IPubSubService, self.service)
     1651        self.resource.create = create
     1652        verify.verifyObject(iwokkel.IPubSubResource, self.resource)
    15531653        d = self.handleRequest(xml)
    15541654        d.addCallback(cb)
    15551655        return d
    15561656
    15571657
    1558     def test_onCreateChanged(self):
     1658    def test_on_createChanged(self):
    15591659        """
    15601660        Replies to create node requests return the created node if changed.
    15611661        """
     
    15791679            self.assertEqual(u'myrenamednode',
    15801680                             element.create.getAttribute('node'))
    15811681
    1582         self.service.create = create
    1583         verify.verifyObject(iwokkel.IPubSubService, self.service)
     1682        self.resource.create = create
     1683        verify.verifyObject(iwokkel.IPubSubResource, self.resource)
    15841684        d = self.handleRequest(xml)
    15851685        d.addCallback(cb)
    15861686        return d
    15871687
    15881688
    1589     def test_onCreateInstant(self):
     1689    def test_on_createInstant(self):
    15901690        """
    15911691        Replies to create instant node requests return the created node.
    15921692        """
     
    16091709            self.assertEqual(NS_PUBSUB, element.create.uri)
    16101710            self.assertEqual(u'random', element.create.getAttribute('node'))
    16111711
    1612         self.service.create = create
    1613         verify.verifyObject(iwokkel.IPubSubService, self.service)
     1712        self.resource.create = create
     1713        verify.verifyObject(iwokkel.IPubSubResource, self.resource)
    16141714        d = self.handleRequest(xml)
    16151715        d.addCallback(cb)
    16161716        return d
    16171717
    16181718
    1619     def test_onDefault(self):
     1719    def test_on_default(self):
    16201720        """
    16211721        A default request should result in
    16221722        L{PubSubService.getDefaultConfiguration} being called.
     
    16411741                     "label": "Deliver payloads with event notifications"}
    16421742                }
    16431743
    1644         def getDefaultConfiguration(request):
     1744        def default(request):
    16451745            return defer.succeed({})
    16461746
    16471747        def cb(element):
     
    16511751            form = data_form.Form.fromElement(element.default.x)
    16521752            self.assertEqual(NS_PUBSUB_CONFIG, form.formNamespace)
    16531753
    1654         self.service.getConfigurationOptions = getConfigurationOptions
    1655         self.service.getDefaultConfiguration = getDefaultConfiguration
    1656         verify.verifyObject(iwokkel.IPubSubService, self.service)
     1754        self.resource.getConfigurationOptions = getConfigurationOptions
     1755        self.resource.default = default
     1756        verify.verifyObject(iwokkel.IPubSubResource, self.resource)
    16571757        d = self.handleRequest(xml)
    16581758        d.addCallback(cb)
    16591759        return d
    16601760
    16611761
    1662     def test_onDefaultCollection(self):
     1762    def test_on_defaultCollection(self):
    16631763        """
    16641764        Responses to default requests should depend on passed node type.
    16651765        """
     
    16901790                     "label": "Deliver payloads with event notifications"}
    16911791                }
    16921792
    1693         def getDefaultConfiguration(request):
     1793        def default(request):
    16941794            return defer.succeed({})
    16951795
    1696         self.service.getConfigurationOptions = getConfigurationOptions
    1697         self.service.getDefaultConfiguration = getDefaultConfiguration
    1698         verify.verifyObject(iwokkel.IPubSubService, self.service)
     1796        self.resource.getConfigurationOptions = getConfigurationOptions
     1797        self.resource.default = default
     1798        verify.verifyObject(iwokkel.IPubSubResource, self.resource)
    16991799        return self.handleRequest(xml)
    17001800
    17011801
    1702     def test_onDefaultUnknownNodeType(self):
     1802    def test_on_defaultUnknownNodeType(self):
    17031803        """
    17041804        A default request should result in
    1705         L{PubSubService.getDefaultConfiguration} being called.
     1805        L{PubSubResource.default} being called.
    17061806        """
    17071807
    17081808        xml = """
     
    17241824        </iq>
    17251825        """
    17261826
    1727         def getDefaultConfiguration(request):
     1827        def default(request):
    17281828            self.fail("Unexpected call to getConfiguration")
    17291829
    17301830        def cb(result):
    17311831            self.assertEquals('not-acceptable', result.condition)
    17321832
    1733         self.service.getDefaultConfiguration = getDefaultConfiguration
    1734         verify.verifyObject(iwokkel.IPubSubService, self.service)
     1833        self.resource.default = default
     1834        verify.verifyObject(iwokkel.IPubSubResource, self.resource)
    17351835        d = self.handleRequest(xml)
    17361836        self.assertFailure(d, error.StanzaError)
    17371837        d.addCallback(cb)
    17381838        return d
    17391839
    17401840
    1741     def test_onConfigureGet(self):
     1841    def test_on_configureGet(self):
    17421842        """
    1743         On a node configuration get request L{PubSubService.getConfiguration}
    1744         is called and results in a data form with the configuration.
     1843        On a node configuration get
     1844        requestL{PubSubResource.configureGet} is called and results in a
     1845        data form with the configuration.
    17451846        """
    17461847
    17471848        xml = """
     
    17661867                     "label": "Owner of the node"}
    17671868                }
    17681869
    1769         def getConfiguration(request):
     1870        def configureGet(request):
    17701871            return defer.succeed({'pubsub#deliver_payloads': '0',
    17711872                                  'pubsub#persist_items': '1',
    17721873                                  'pubsub#owner': JID('user@example.org'),
     
    18001901
    18011902            self.assertNotIn('x-myfield', fields)
    18021903
    1803 
    1804         self.service.getConfigurationOptions = getConfigurationOptions
    1805         self.service.getConfiguration = getConfiguration
    1806         verify.verifyObject(iwokkel.IPubSubService, self.service)
     1904        self.resource.getConfigurationOptions = getConfigurationOptions
     1905        self.resource.configureGet = configureGet
     1906        verify.verifyObject(iwokkel.IPubSubResource, self.resource)
    18071907        d = self.handleRequest(xml)
    18081908        d.addCallback(cb)
    18091909        return d
    18101910
    18111911
    1812     def test_onConfigureSet(self):
     1912    def test_on_configureSet(self):
    18131913        """
    18141914        On a node configuration set request the Data Form is parsed and
    1815         L{PubSubService.setConfiguration} is called with the passed options.
     1915        L{PubSubResource.configureSet} is called with the passed options.
    18161916        """
    18171917
    18181918        xml = """
     
    18421942                     "label": "Deliver payloads with event notifications"}
    18431943                }
    18441944
    1845         def setConfiguration(request):
     1945        def configureSet(request):
    18461946            self.assertEqual({'pubsub#deliver_payloads': False,
    18471947                              'pubsub#persist_items': True}, request.options)
    18481948            return defer.succeed(None)
    18491949
    1850         self.service.getConfigurationOptions = getConfigurationOptions
    1851         self.service.setConfiguration = setConfiguration
    1852         verify.verifyObject(iwokkel.IPubSubService, self.service)
     1950        self.resource.getConfigurationOptions = getConfigurationOptions
     1951        self.resource.configureSet = configureSet
     1952        verify.verifyObject(iwokkel.IPubSubResource, self.resource)
    18531953        return self.handleRequest(xml)
    18541954
    18551955
    1856     def test_onConfigureSetCancel(self):
     1956    def test_on_configureSetCancel(self):
    18571957        """
    1858         The node configuration is cancelled, L{PubSubService.setConfiguration}
    1859         not called.
     1958        The node configuration is cancelled,
     1959        L{PubSubResource.configureSet} not called.
    18601960        """
    18611961
    18621962        xml = """
     
    18741974        </iq>
    18751975        """
    18761976
    1877         def setConfiguration(request):
     1977        def configureSet(request):
    18781978            self.fail("Unexpected call to setConfiguration")
    18791979
    1880         self.service.setConfiguration = setConfiguration
    1881         verify.verifyObject(iwokkel.IPubSubService, self.service)
     1980        self.resource.configureSet = configureSet
     1981        verify.verifyObject(iwokkel.IPubSubResource, self.resource)
    18821982        return self.handleRequest(xml)
    18831983
    18841984
    1885     def test_onConfigureSetIgnoreUnknown(self):
     1985    def test_on_configureSetIgnoreUnknown(self):
    18861986        """
    18871987        On a node configuration set request unknown fields should be ignored.
    18881988        """
     
    19142014                     "label": "Deliver payloads with event notifications"}
    19152015                }
    19162016
    1917         def setConfiguration(request):
     2017        def configureSet(request):
    19182018            self.assertEquals(['pubsub#deliver_payloads'],
    19192019                              request.options.keys())
    19202020
    1921         self.service.getConfigurationOptions = getConfigurationOptions
    1922         self.service.setConfiguration = setConfiguration
    1923         verify.verifyObject(iwokkel.IPubSubService, self.service)
     2021        self.resource.getConfigurationOptions = getConfigurationOptions
     2022        self.resource.configureSet = configureSet
     2023        verify.verifyObject(iwokkel.IPubSubResource, self.resource)
    19242024        return self.handleRequest(xml)
    19252025
    19262026
    1927     def test_onConfigureSetBadFormType(self):
     2027    def test_on_configureSetBadFormType(self):
    19282028        """
    19292029        On a node configuration set request unknown fields should be ignored.
    19302030        """
     
    19552055        return d
    19562056
    19572057
    1958     def test_onItems(self):
     2058    def test_on_items(self):
    19592059        """
    19602060        On a items request, return all items for the given node.
    19612061        """
     
    19812081            self.assertEqual(NS_PUBSUB, item.uri)
    19822082            self.assertEqual('current', item['id'])
    19832083
    1984         self.service.items = items
     2084        self.resource.items = items
     2085        verify.verifyObject(iwokkel.IPubSubResource, self.resource)
    19852086        d = self.handleRequest(xml)
    19862087        d.addCallback(cb)
    19872088        return d
    19882089
    19892090
    1990     def test_onRetract(self):
     2091    def test_on_retract(self):
    19912092        """
    1992         A retract request should result in L{PubSubService.retract} being
    1993         called.
     2093        A retract request should result in L{PubSubResource.retract}
     2094        being called.
    19942095        """
    19952096
    19962097        xml = """
     
    20082109        def retract(request):
    20092110            return defer.succeed(None)
    20102111
    2011         self.service.retract = retract
     2112        self.resource.retract = retract
     2113        verify.verifyObject(iwokkel.IPubSubResource, self.resource)
    20122114        return self.handleRequest(xml)
    20132115
    20142116
    2015     def test_onPurge(self):
     2117    def test_on_purge(self):
    20162118        """
    2017         A purge request should result in L{PubSubService.purge} being
     2119        A purge request should result in L{PubSubResource.purge} being
    20182120        called.
    20192121        """
    20202122
     
    20302132        def purge(request):
    20312133            return defer.succeed(None)
    20322134
    2033         self.service.purge = purge
     2135        self.resource.purge = purge
     2136        verify.verifyObject(iwokkel.IPubSubResource, self.resource)
    20342137        return self.handleRequest(xml)
    20352138
    20362139
    2037     def test_onDelete(self):
     2140    def test_on_delete(self):
    20382141        """
    2039         A delete request should result in L{PubSubService.delete} being
     2142        A delete request should result in L{PubSubResource.delete} being
    20402143        called.
    20412144        """
    20422145
     
    20522155        def delete(request):
    20532156            return defer.succeed(None)
    20542157
    2055         self.service.delete = delete
     2158        self.resource.delete = delete
     2159        verify.verifyObject(iwokkel.IPubSubResource, self.resource)
    20562160        return self.handleRequest(xml)
    20572161
    20582162
     
    21032207        self.assertEqual(redirectURI, message.event.delete.redirect['uri'])
    21042208
    21052209
    2106     def test_onSubscriptionsGet(self):
     2210    def test_on_subscriptionsGet(self):
    21072211        """
    21082212        Getting subscription options is not supported.
    21092213        """
     
    21302234        return d
    21312235
    21322236
    2133     def test_onSubscriptionsSet(self):
     2237    def test_on_subscriptionsSet(self):
    21342238        """
    21352239        Setting subscription options is not supported.
    21362240        """
     
    21572261        return d
    21582262
    21592263
    2160     def test_onAffiliationsGet(self):
     2264    def test_on_affiliationsGet(self):
    21612265        """
    21622266        Getting subscription options is not supported.
    21632267        """
     
    21842288        return d
    21852289
    21862290
    2187     def test_onAffiliationsSet(self):
     2291    def test_on_affiliationsSet(self):
    21882292        """
    21892293        Setting subscription options is not supported.
    21902294        """
     
    22112315        return d
    22122316
    22132317
     2318
     2319class PubSubResourceTest(unittest.TestCase):
     2320
     2321    def setUp(self):
     2322        self.resource = pubsub.PubSubResource()
     2323
     2324
     2325    def test_interface(self):
     2326        """
     2327        Do instances of L{pubsub.PubSubResource} provide L{iwokkel.IPubSubResource}?
     2328        """
     2329        verify.verifyObject(iwokkel.IPubSubResource, self.resource)
     2330
     2331
     2332    def test_getNodes(self):
     2333        """
     2334        Default getNodes returns an empty list.
     2335        """
     2336        def cb(nodes):
     2337            self.assertEquals([], nodes)
     2338
     2339        d = self.resource.getNodes(JID('user@example.org/home'),
     2340                                   JID('pubsub.example.org'),
     2341                                   '')
     2342        d.addCallback(cb)
     2343        return d
     2344
     2345
    22142346    def test_publish(self):
    22152347        """
    2216         Non-overridden L{PubSubService.publish} yields unsupported error.
    2217         """
    2218 
    2219         xml = """
    2220         <iq type='set' to='pubsub.example.org'
    2221                        from='user@example.org'>
    2222           <pubsub xmlns='http://jabber.org/protocol/pubsub'>
    2223             <publish node='mynode'/>
    2224           </pubsub>
    2225         </iq>
     2348        Non-overridden L{PubSubResource.publish} yields unsupported
     2349        error.
    22262350        """
    22272351
    22282352        def cb(result):
     
    22312355            self.assertEquals(NS_PUBSUB_ERRORS, result.appCondition.uri)
    22322356            self.assertEquals('publish', result.appCondition['feature'])
    22332357
    2234         d = self.handleRequest(xml)
     2358        d = self.resource.publish(pubsub.PubSubRequest())
    22352359        self.assertFailure(d, error.StanzaError)
    22362360        d.addCallback(cb)
    22372361        return d
     
    22392363
    22402364    def test_subscribe(self):
    22412365        """
    2242         Non-overridden L{PubSubService.subscribe} yields unsupported error.
    2243         """
    2244 
    2245         xml = """
    2246         <iq type='set' to='pubsub.example.org'
    2247                        from='user@example.org'>
    2248           <pubsub xmlns='http://jabber.org/protocol/pubsub'>
    2249             <subscribe node='test' jid='user@example.org/Home'/>
    2250           </pubsub>
    2251         </iq>
     2366        Non-overridden subscriptions yields unsupported error.
    22522367        """
    22532368
    22542369        def cb(result):
     
    22572372            self.assertEquals(NS_PUBSUB_ERRORS, result.appCondition.uri)
    22582373            self.assertEquals('subscribe', result.appCondition['feature'])
    22592374
    2260         d = self.handleRequest(xml)
     2375        d = self.resource.subscribe(pubsub.PubSubRequest())
    22612376        self.assertFailure(d, error.StanzaError)
    22622377        d.addCallback(cb)
    22632378        return d
     
    22652380
    22662381    def test_unsubscribe(self):
    22672382        """
    2268         Non-overridden L{PubSubService.unsubscribe} yields unsupported error.
    2269         """
    2270 
    2271         xml = """
    2272         <iq type='set' to='pubsub.example.org'
    2273                        from='user@example.org'>
    2274           <pubsub xmlns='http://jabber.org/protocol/pubsub'>
    2275             <unsubscribe node='test' jid='user@example.org/Home'/>
    2276           </pubsub>
    2277         </iq>
     2383        Non-overridden unsubscribe yields unsupported error.
    22782384        """
    22792385
    22802386        def cb(result):
     
    22832389            self.assertEquals(NS_PUBSUB_ERRORS, result.appCondition.uri)
    22842390            self.assertEquals('subscribe', result.appCondition['feature'])
    22852391
    2286         d = self.handleRequest(xml)
     2392        d = self.resource.unsubscribe(pubsub.PubSubRequest())
    22872393        self.assertFailure(d, error.StanzaError)
    22882394        d.addCallback(cb)
    22892395        return d
     
    22912397
    22922398    def test_subscriptions(self):
    22932399        """
    2294         Non-overridden L{PubSubService.subscriptions} yields unsupported error.
    2295         """
    2296 
    2297         xml = """
    2298         <iq type='get' to='pubsub.example.org'
    2299                        from='user@example.org'>
    2300           <pubsub xmlns='http://jabber.org/protocol/pubsub'>
    2301             <subscriptions/>
    2302           </pubsub>
    2303         </iq>
     2400        Non-overridden subscriptions yields unsupported error.
    23042401        """
    23052402
    23062403        def cb(result):
     
    23102407            self.assertEquals('retrieve-subscriptions',
    23112408                              result.appCondition['feature'])
    23122409
    2313         d = self.handleRequest(xml)
     2410        d = self.resource.subscriptions(pubsub.PubSubRequest())
    23142411        self.assertFailure(d, error.StanzaError)
    23152412        d.addCallback(cb)
    23162413        return d
     
    23182415
    23192416    def test_affiliations(self):
    23202417        """
    2321         Non-overridden L{PubSubService.affiliations} yields unsupported error.
    2322         """
    2323 
    2324         xml = """
    2325         <iq type='get' to='pubsub.example.org'
    2326                        from='user@example.org'>
    2327           <pubsub xmlns='http://jabber.org/protocol/pubsub'>
    2328             <affiliations/>
    2329           </pubsub>
    2330         </iq>
     2418        Non-overridden affiliations yields unsupported error.
    23312419        """
    23322420
    23332421        def cb(result):
     
    23372425            self.assertEquals('retrieve-affiliations',
    23382426                              result.appCondition['feature'])
    23392427
    2340         d = self.handleRequest(xml)
     2428        d = self.resource.affiliations(pubsub.PubSubRequest())
    23412429        self.assertFailure(d, error.StanzaError)
    23422430        d.addCallback(cb)
    23432431        return d
     
    23452433
    23462434    def test_create(self):
    23472435        """
    2348         Non-overridden L{PubSubService.create} yields unsupported error.
    2349         """
    2350 
    2351         xml = """
    2352         <iq type='set' to='pubsub.example.org'
    2353                        from='user@example.org'>
    2354           <pubsub xmlns='http://jabber.org/protocol/pubsub'>
    2355             <create node='mynode'/>
    2356           </pubsub>
    2357         </iq>
     2436        Non-overridden create yields unsupported error.
    23582437        """
    23592438
    23602439        def cb(result):
     
    23632442            self.assertEquals(NS_PUBSUB_ERRORS, result.appCondition.uri)
    23642443            self.assertEquals('create-nodes', result.appCondition['feature'])
    23652444
    2366         d = self.handleRequest(xml)
     2445        d = self.resource.create(pubsub.PubSubRequest())
    23672446        self.assertFailure(d, error.StanzaError)
    23682447        d.addCallback(cb)
    23692448        return d
    23702449
    23712450
    2372     def test_getDefaultConfiguration(self):
     2451    def test_default(self):
    23732452        """
    2374         Non-overridden L{PubSubService.getDefaultConfiguration} yields
    2375         unsupported error.
    2376         """
    2377 
    2378         xml = """
    2379         <iq type='get' to='pubsub.example.org'
    2380                        from='user@example.org'>
    2381           <pubsub xmlns='http://jabber.org/protocol/pubsub#owner'>
    2382             <default/>
    2383           </pubsub>
    2384         </iq>
     2453        Non-overridden default yields unsupported error.
    23852454        """
    23862455
    23872456        def cb(result):
    23882457            self.assertEquals('feature-not-implemented', result.condition)
    23892458            self.assertEquals('unsupported', result.appCondition.name)
    23902459            self.assertEquals(NS_PUBSUB_ERRORS, result.appCondition.uri)
    2391             self.assertEquals('retrieve-default', result.appCondition['feature'])
     2460            self.assertEquals('retrieve-default',
     2461                              result.appCondition['feature'])
    23922462
    2393         d = self.handleRequest(xml)
     2463        d = self.resource.default(pubsub.PubSubRequest())
    23942464        self.assertFailure(d, error.StanzaError)
    23952465        d.addCallback(cb)
    23962466        return d
    23972467
    23982468
    2399     def test_getConfiguration(self):
     2469    def test_configureGet(self):
    24002470        """
    2401         Non-overridden L{PubSubService.getConfiguration} yields unsupported
     2471        Non-overridden configureGet yields unsupported
    24022472        error.
    24032473        """
    24042474
    2405         xml = """
    2406         <iq type='get' to='pubsub.example.org'
    2407                        from='user@example.org'>
    2408           <pubsub xmlns='http://jabber.org/protocol/pubsub#owner'>
    2409             <configure/>
    2410           </pubsub>
    2411         </iq>
    2412         """
    2413 
    24142475        def cb(result):
    24152476            self.assertEquals('feature-not-implemented', result.condition)
    24162477            self.assertEquals('unsupported', result.appCondition.name)
    24172478            self.assertEquals(NS_PUBSUB_ERRORS, result.appCondition.uri)
    24182479            self.assertEquals('config-node', result.appCondition['feature'])
    24192480
    2420         d = self.handleRequest(xml)
     2481        d = self.resource.configureGet(pubsub.PubSubRequest())
    24212482        self.assertFailure(d, error.StanzaError)
    24222483        d.addCallback(cb)
    24232484        return d
    24242485
    24252486
    2426     def test_setConfiguration(self):
     2487    def test_configureSet(self):
    24272488        """
    2428         Non-overridden L{PubSubService.setConfiguration} yields unsupported
    2429         error.
    2430         """
    2431 
    2432         xml = """
    2433         <iq type='set' to='pubsub.example.org'
    2434                        from='user@example.org'>
    2435           <pubsub xmlns='http://jabber.org/protocol/pubsub#owner'>
    2436             <configure node='test'>
    2437               <x xmlns='jabber:x:data' type='submit'>
    2438                 <field var='FORM_TYPE' type='hidden'>
    2439                   <value>http://jabber.org/protocol/pubsub#node_config</value>
    2440                 </field>
    2441                 <field var='pubsub#deliver_payloads'><value>0</value></field>
    2442                 <field var='pubsub#persist_items'><value>1</value></field>
    2443               </x>
    2444             </configure>
    2445           </pubsub>
    2446         </iq>
     2489        Non-overridden configureSet yields unsupported error.
    24472490        """
    24482491
    24492492        def cb(result):
     
    24522495            self.assertEquals(NS_PUBSUB_ERRORS, result.appCondition.uri)
    24532496            self.assertEquals('config-node', result.appCondition['feature'])
    24542497
    2455         d = self.handleRequest(xml)
     2498        d = self.resource.configureSet(pubsub.PubSubRequest())
    24562499        self.assertFailure(d, error.StanzaError)
    24572500        d.addCallback(cb)
    24582501        return d
     
    24602503
    24612504    def test_items(self):
    24622505        """
    2463         Non-overridden L{PubSubService.items} yields unsupported error.
    2464         """
    2465         xml = """
    2466         <iq type='get' to='pubsub.example.org'
    2467                        from='user@example.org'>
    2468           <pubsub xmlns='http://jabber.org/protocol/pubsub'>
    2469             <items node='test'/>
    2470           </pubsub>
    2471         </iq>
     2506        Non-overridden items yields unsupported error.
    24722507        """
    24732508
    24742509        def cb(result):
     
    24772512            self.assertEquals(NS_PUBSUB_ERRORS, result.appCondition.uri)
    24782513            self.assertEquals('retrieve-items', result.appCondition['feature'])
    24792514
    2480         d = self.handleRequest(xml)
     2515        d = self.resource.items(pubsub.PubSubRequest())
    24812516        self.assertFailure(d, error.StanzaError)
    24822517        d.addCallback(cb)
    24832518        return d
     
    24852520
    24862521    def test_retract(self):
    24872522        """
    2488         Non-overridden L{PubSubService.retract} yields unsupported error.
    2489         """
    2490         xml = """
    2491         <iq type='set' to='pubsub.example.org'
    2492                        from='user@example.org'>
    2493           <pubsub xmlns='http://jabber.org/protocol/pubsub'>
    2494             <retract node='test'>
    2495               <item id='item1'/>
    2496               <item id='item2'/>
    2497             </retract>
    2498           </pubsub>
    2499         </iq>
     2523        Non-overridden retract yields unsupported error.
    25002524        """
    25012525
    25022526        def cb(result):
     
    25052529            self.assertEquals(NS_PUBSUB_ERRORS, result.appCondition.uri)
    25062530            self.assertEquals('retract-items', result.appCondition['feature'])
    25072531
    2508         d = self.handleRequest(xml)
     2532        d = self.resource.retract(pubsub.PubSubRequest())
    25092533        self.assertFailure(d, error.StanzaError)
    25102534        d.addCallback(cb)
    25112535        return d
     
    25132537
    25142538    def test_purge(self):
    25152539        """
    2516         Non-overridden L{PubSubService.purge} yields unsupported error.
    2517         """
    2518         xml = """
    2519         <iq type='set' to='pubsub.example.org'
    2520                        from='user@example.org'>
    2521           <pubsub xmlns='http://jabber.org/protocol/pubsub#owner'>
    2522             <purge node='test'/>
    2523           </pubsub>
    2524         </iq>
     2540        Non-overridden purge yields unsupported error.
    25252541        """
    25262542
    25272543        def cb(result):
     
    25302546            self.assertEquals(NS_PUBSUB_ERRORS, result.appCondition.uri)
    25312547            self.assertEquals('purge-nodes', result.appCondition['feature'])
    25322548
    2533         d = self.handleRequest(xml)
     2549        d = self.resource.purge(pubsub.PubSubRequest())
    25342550        self.assertFailure(d, error.StanzaError)
    25352551        d.addCallback(cb)
    25362552        return d
     
    25382554
    25392555    def test_delete(self):
    25402556        """
    2541         Non-overridden L{PubSubService.delete} yields unsupported error.
    2542         """
    2543         xml = """
    2544         <iq type='set' to='pubsub.example.org'
    2545                        from='user@example.org'>
    2546           <pubsub xmlns='http://jabber.org/protocol/pubsub#owner'>
    2547             <delete node='test'/>
    2548           </pubsub>
    2549         </iq>
     2557        Non-overridden delete yields unsupported error.
    25502558        """
    25512559
    25522560        def cb(result):
     
    25552563            self.assertEquals(NS_PUBSUB_ERRORS, result.appCondition.uri)
    25562564            self.assertEquals('delete-nodes', result.appCondition['feature'])
    25572565
    2558         d = self.handleRequest(xml)
     2566        d = self.resource.delete(pubsub.PubSubRequest())
    25592567        self.assertFailure(d, error.StanzaError)
    25602568        d.addCallback(cb)
    25612569        return d
Note: See TracBrowser for help on using the repository browser.