Changeset 84:3fe44cf07366


Ignore:
Timestamp:
Jan 5, 2010, 2:55:40 PM (12 years ago)
Author:
Ralph Meijer <ralphm@…>
Branch:
default
Message:

Add support for pubsub subscription identifiers

Location:
wokkel
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • wokkel/pubsub.py

    r83 r84  
    103103    A subscription to a node.
    104104
    105     @ivar nodeIdentifier: The identifier of the node subscribed to.
    106                           The root node is denoted by C{None}.
     105    @ivar nodeIdentifier: The identifier of the node subscribed to.  The root
     106        node is denoted by C{None}.
     107    @type nodeIdentifier: C{unicode}
     108
    107109    @ivar subscriber: The subscribing entity.
     110    @type subscriber: L{jid.JID}
     111
    108112    @ivar state: The subscription state. One of C{'subscribed'}, C{'pending'},
    109113                 C{'unconfigured'}.
     114    @type state: C{unicode}
     115
    110116    @ivar options: Optional list of subscription options.
    111     @type options: C{dict}.
    112     """
    113 
    114     def __init__(self, nodeIdentifier, subscriber, state, options=None):
     117    @type options: C{dict}
     118
     119    @ivar subscriptionIdentifier: Optional subscription identifier.
     120    @type subscriptionIdentifier: C{unicode}
     121    """
     122
     123    def __init__(self, nodeIdentifier, subscriber, state, options=None,
     124                       subscriptionIdentifier=None):
    115125        self.nodeIdentifier = nodeIdentifier
    116126        self.subscriber = subscriber
    117127        self.state = state
    118128        self.options = options or {}
     129        self.subscriptionIdentifier = subscriptionIdentifier
     130
     131
     132    @staticmethod
     133    def fromElement(element):
     134        return Subscription(
     135                element.getAttribute('node'),
     136                jid.JID(element.getAttribute('jid')),
     137                element.getAttribute('subscription'),
     138                subscriptionIdentifier=element.getAttribute('subid'))
     139
     140
     141    def toElement(self):
     142        """
     143        Return the DOM representation of this subscription.
     144
     145        @rtype: L{domish.Element}
     146        """
     147        element = domish.Element((None, 'subscription'))
     148        if self.nodeIdentifier:
     149            element['node'] = self.nodeIdentifier
     150        element['jid'] = unicode(self.subscriber)
     151        element['subscription'] = self.state
     152        if self.subscriptionIdentifier:
     153            element['subid'] = self.subscriptionIdentifier
     154        return element
    119155
    120156
     
    230266        'publish': ['node', 'items'],
    231267        'subscribe': ['nodeOrEmpty', 'jid', 'optionsWithSubscribe'],
    232         'unsubscribe': ['nodeOrEmpty', 'jid'],
    233         'optionsGet': ['nodeOrEmpty', 'jid'],
    234         'optionsSet': ['nodeOrEmpty', 'jid', 'options'],
     268        'unsubscribe': ['nodeOrEmpty', 'jid', 'subidOrNone'],
     269        'optionsGet': ['nodeOrEmpty', 'jid', 'subidOrNone'],
     270        'optionsSet': ['nodeOrEmpty', 'jid', 'options', 'subidOrNone'],
    235271        'subscriptions': [],
    236272        'affiliations': [],
     
    239275        'configureGet': ['nodeOrEmpty'],
    240276        'configureSet': ['nodeOrEmpty', 'configure'],
    241         'items': ['node', 'maxItems', 'itemIdentifiers'],
     277        'items': ['node', 'maxItems', 'itemIdentifiers', 'subidOrNone'],
    242278        'retract': ['node', 'itemIdentifiers'],
    243279        'purge': ['node'],
     
    430466    def _render_maxItems(self, verbElement):
    431467        """
    432         Parse maximum items into an items request.
     468        Render maximum items into an items request.
    433469        """
    434470        if self.maxItems:
    435471            verbElement['max_items'] = unicode(self.maxItems)
     472
     473
     474    def _parse_subidOrNone(self, verbElement):
     475        """
     476        Parse subscription identifier out of a request.
     477        """
     478        self.subscriptionIdentifier = verbElement.getAttribute("subid")
     479
     480
     481    def _render_subidOrNone(self, verbElement):
     482        """
     483        Render subscription identifier into a request.
     484        """
     485        if self.subscriptionIdentifier:
     486            verbElement['subid'] = self.subscriptionIdentifier
    436487
    437488
     
    730781        @param service: The publish subscribe service that keeps the node.
    731782        @type service: L{JID}
     783
    732784        @param nodeIdentifier: The identifier of the node.
    733785        @type nodeIdentifier: C{unicode}
     786
    734787        @param subscriber: The entity to subscribe to the node. This entity
    735                            will get notifications of new published items.
     788            will get notifications of new published items.
    736789        @type subscriber: L{JID}
     790
    737791        @param options: Subscription options.
    738         @type options: C{dict}.
     792        @type options: C{dict}
     793
     794        @return: Deferred that fires with L{Subscription} or errbacks with
     795            L{SubscriptionPending} or L{SubscriptionUnconfigured}.
     796        @rtype: L{defer.Deferred}
    739797        """
    740798        request = PubSubRequest('subscribe')
     
    751809
    752810        def cb(iq):
    753             subscription = iq.pubsub.subscription["subscription"]
    754 
    755             if subscription == 'pending':
    756                 raise SubscriptionPending
    757             elif subscription == 'unconfigured':
    758                 raise SubscriptionUnconfigured
     811            subscription = Subscription.fromElement(iq.pubsub.subscription)
     812
     813            if subscription.state == 'pending':
     814                raise SubscriptionPending()
     815            elif subscription.state == 'unconfigured':
     816                raise SubscriptionUnconfigured()
    759817            else:
    760818                # we assume subscription == 'subscribed'
    761819                # any other value would be invalid, but that should have
    762820                # yielded a stanza error.
    763                 return None
     821                return subscription
    764822
    765823        d = request.send(self.xmlstream)
     
    768826
    769827
    770     def unsubscribe(self, service, nodeIdentifier, subscriber, sender=None):
     828    def unsubscribe(self, service, nodeIdentifier, subscriber,
     829                          subscriptionIdentifier=None, sender=None):
    771830        """
    772831        Unsubscribe from a publish subscribe node.
     
    774833        @param service: The publish subscribe service that keeps the node.
    775834        @type service: L{JID}
     835
    776836        @param nodeIdentifier: The identifier of the node.
    777837        @type nodeIdentifier: C{unicode}
     838
    778839        @param subscriber: The entity to unsubscribe from the node.
    779840        @type subscriber: L{JID}
     841
     842        @param subscriptionIdentifier: Optional subscription identifier.
     843        @type subscriptionIdentifier: C{unicode}
    780844        """
    781845        request = PubSubRequest('unsubscribe')
     
    783847        request.nodeIdentifier = nodeIdentifier
    784848        request.subscriber = subscriber
     849        request.subscriptionIdentifier = subscriptionIdentifier
    785850        request.sender = sender
    786851        return request.send(self.xmlstream)
     
    806871
    807872
    808     def items(self, service, nodeIdentifier, maxItems=None, sender=None):
     873    def items(self, service, nodeIdentifier, maxItems=None,
     874              subscriptionIdentifier=None, sender=None):
    809875        """
    810876        Retrieve previously published items from a publish subscribe node.
     
    812878        @param service: The publish subscribe service that keeps the node.
    813879        @type service: L{JID}
     880
    814881        @param nodeIdentifier: The identifier of the node.
    815882        @type nodeIdentifier: C{unicode}
     883
    816884        @param maxItems: Optional limit on the number of retrieved items.
    817885        @type maxItems: C{int}
     886
     887        @param subscriptionIdentifier: Optional subscription identifier. In
     888            case the node has been subscribed to multiple times, this narrows
     889            the results to the specific subscription.
     890        @type subscriptionIdentifier: C{unicode}
    818891        """
    819892        request = PubSubRequest('items')
     
    822895        if maxItems:
    823896            request.maxItems = str(int(maxItems))
     897        request.subscriptionIdentifier = subscriptionIdentifier
    824898        request.sender = sender
    825899
     
    836910
    837911
    838     def getOptions(self, service, nodeIdentifier, subscriber, sender=None):
     912    def getOptions(self, service, nodeIdentifier, subscriber,
     913                         subscriptionIdentifier=None, sender=None):
    839914        """
    840915        Get subscription options.
     
    848923        @param subscriber: The entity subscribed to the node.
    849924        @type subscriber: L{JID}
     925
     926        @param subscriptionIdentifier: Optional subscription identifier.
     927        @type subscriptionIdentifier: C{unicode}
    850928
    851929        @rtype: L{data_form.Form}
     
    855933        request.nodeIdentifier = nodeIdentifier
    856934        request.subscriber = subscriber
     935        request.subscriptionIdentifier = subscriptionIdentifier
    857936        request.sender = sender
    858937
     
    869948
    870949    def setOptions(self, service, nodeIdentifier, subscriber,
    871                          options, sender=None):
     950                         options, subscriptionIdentifier=None, sender=None):
    872951        """
    873952        Set subscription options.
     
    884963        @param options: Subscription options.
    885964        @type options: C{dict}.
     965
     966        @param subscriptionIdentifier: Optional subscription identifier.
     967        @type subscriptionIdentifier: C{unicode}
    886968        """
    887969        request = PubSubRequest('optionsSet')
     
    889971        request.nodeIdentifier = nodeIdentifier
    890972        request.subscriber = subscriber
     973        request.subscriptionIdentifier = subscriptionIdentifier
    891974        request.sender = sender
    892975
     
    10931176    def _toResponse_subscribe(self, result, resource, request):
    10941177        response = domish.Element((NS_PUBSUB, "pubsub"))
    1095         subscription = response.addElement("subscription")
    1096         if result.nodeIdentifier:
    1097             subscription["node"] = result.nodeIdentifier
    1098         subscription["jid"] = result.subscriber.full()
    1099         subscription["subscription"] = result.state
     1178        subscription = response.addChild(result.toElement())
    11001179        return response
    11011180
     
    11051184        subscriptions = response.addElement('subscriptions')
    11061185        for subscription in result:
    1107             item = subscriptions.addElement('subscription')
    1108             item['node'] = subscription.nodeIdentifier
    1109             item['jid'] = subscription.subscriber.full()
    1110             item['subscription'] = subscription.state
     1186            subscriptions.addChild(subscription.toElement())
    11111187        return response
    11121188
  • wokkel/test/test_pubsub.py

    r83 r84  
    4242
    4343    return d, func
     44
     45
     46class SubscriptionTest(unittest.TestCase):
     47    """
     48    Tests for L{pubsub.Subscription}.
     49    """
     50
     51    def test_fromElement(self):
     52        """
     53        fromElement parses a subscription from XML DOM.
     54        """
     55        xml = """
     56        <subscription node='test' jid='user@example.org/Home'
     57                      subscription='pending'/>
     58        """
     59        subscription = pubsub.Subscription.fromElement(parseXml(xml))
     60        self.assertEqual('test', subscription.nodeIdentifier)
     61        self.assertEqual(JID('user@example.org/Home'), subscription.subscriber)
     62        self.assertEqual('pending', subscription.state)
     63        self.assertIdentical(None, subscription.subscriptionIdentifier)
     64
     65
     66    def test_fromElementWithSubscriptionIdentifier(self):
     67        """
     68        A subscription identifier in the subscription should be parsed, too.
     69        """
     70        xml = """
     71        <subscription node='test' jid='user@example.org/Home' subid='1234'
     72                      subscription='pending'/>
     73        """
     74        subscription = pubsub.Subscription.fromElement(parseXml(xml))
     75        self.assertEqual('1234', subscription.subscriptionIdentifier)
     76
     77
     78    def test_toElement(self):
     79        """
     80        Rendering a Subscription should yield the proper attributes.
     81        """
     82        subscription = pubsub.Subscription('test',
     83                                           JID('user@example.org/Home'),
     84                                           'pending')
     85        element = subscription.toElement()
     86        self.assertEqual('subscription', element.name)
     87        self.assertEqual(None, element.uri)
     88        self.assertEqual('test', element.getAttribute('node'))
     89        self.assertEqual('user@example.org/Home', element.getAttribute('jid'))
     90        self.assertEqual('pending', element.getAttribute('subscription'))
     91        self.assertFalse(element.hasAttribute('subid'))
     92
     93
     94    def test_toElementEmptyNodeIdentifier(self):
     95        """
     96        The empty node identifier should not yield a node attribute.
     97        """
     98        subscription = pubsub.Subscription('',
     99                                           JID('user@example.org/Home'),
     100                                           'pending')
     101        element = subscription.toElement()
     102        self.assertFalse(element.hasAttribute('node'))
     103
     104
     105    def test_toElementWithSubscriptionIdentifier(self):
     106        """
     107        The subscription identifier, if set, is in the subid attribute.
     108        """
     109        subscription = pubsub.Subscription('test',
     110                                           JID('user@example.org/Home'),
     111                                           'pending',
     112                                           subscriptionIdentifier='1234')
     113        element = subscription.toElement()
     114        self.assertEqual('1234', element.getAttribute('subid'))
     115
    44116
    45117
     
    444516
    445517
     518    def test_subscribeReturnsSubscription(self):
     519        """
     520        A successful subscription should return a Subscription instance.
     521        """
     522        def cb(subscription):
     523            self.assertEqual(JID('user@example.org'), subscription.subscriber)
     524
     525        d = self.protocol.subscribe(JID('pubsub.example.org'), 'test',
     526                                      JID('user@example.org'))
     527        d.addCallback(cb)
     528
     529        iq = self.stub.output[-1]
     530
     531        response = toResponse(iq, 'result')
     532        pubsub = response.addElement((NS_PUBSUB, 'pubsub'))
     533        subscription = pubsub.addElement('subscription')
     534        subscription['node'] = 'test'
     535        subscription['jid'] = 'user@example.org'
     536        subscription['subscription'] = 'subscribed'
     537        self.stub.send(response)
     538        return d
     539
     540
    446541    def test_subscribePending(self):
    447542        """
     
    534629        subscription['jid'] = 'user@example.org'
    535630        subscription['subscription'] = 'subscribed'
     631        self.stub.send(response)
     632        return d
     633
     634
     635    def test_subscribeReturningSubscriptionIdentifier(self):
     636        """
     637        Test sending subscription request with subscription identifier.
     638        """
     639        def cb(subscription):
     640            self.assertEqual('1234', subscription.subscriptionIdentifier)
     641
     642        d = self.protocol.subscribe(JID('pubsub.example.org'), 'test',
     643                                      JID('user@example.org'))
     644        d.addCallback(cb)
     645
     646        iq = self.stub.output[-1]
     647
     648        response = toResponse(iq, 'result')
     649        pubsub = response.addElement((NS_PUBSUB, 'pubsub'))
     650        subscription = pubsub.addElement('subscription')
     651        subscription['node'] = 'test'
     652        subscription['jid'] = 'user@example.org'
     653        subscription['subscription'] = 'subscribed'
     654        subscription['subid'] = '1234'
    536655        self.stub.send(response)
    537656        return d
     
    575694
    576695
     696    def test_unsubscribeWithSubscriptionIdentifier(self):
     697        """
     698        Test sending unsubscription request with subscription identifier.
     699        """
     700        d = self.protocol.unsubscribe(JID('pubsub.example.org'), 'test',
     701                                      JID('user@example.org'),
     702                                      subscriptionIdentifier='1234')
     703
     704        iq = self.stub.output[-1]
     705        child = iq.pubsub.unsubscribe
     706        self.assertEquals('1234', child['subid'])
     707
     708        self.stub.send(toResponse(iq, 'result'))
     709        return d
     710
     711
    577712    def test_items(self):
    578713        """
     
    641776
    642777
     778    def test_itemsWithSubscriptionIdentifier(self):
     779        """
     780        Test sending items request with a subscription identifier.
     781        """
     782
     783        d = self.protocol.items(JID('pubsub.example.org'), 'test',
     784                               subscriptionIdentifier='1234')
     785
     786        iq = self.stub.output[-1]
     787        child = iq.pubsub.items
     788        self.assertEquals('1234', child['subid'])
     789
     790        response = toResponse(iq, 'result')
     791        items = response.addElement((NS_PUBSUB, 'pubsub')).addElement('items')
     792        items['node'] = 'test'
     793
     794        self.stub.send(response)
     795        return d
     796
     797
    643798    def test_itemsWithSender(self):
    644799        """
     
    701856
    702857
     858    def test_getOptionsWithSubscriptionIdentifier(self):
     859        """
     860        Getting options with a subid should have the subid in the request.
     861        """
     862
     863        d = self.protocol.getOptions(JID('pubsub.example.org'), 'test',
     864                                     JID('user@example.org'),
     865                                     sender=JID('user@example.org'),
     866                                     subscriptionIdentifier='1234')
     867
     868        iq = self.stub.output[-1]
     869        child = iq.pubsub.options
     870        self.assertEqual('1234', child['subid'])
     871
     872        # Send response
     873        form = data_form.Form('form', formNamespace=NS_PUBSUB_SUBSCRIBE_OPTIONS)
     874        form.addField(data_form.Field('boolean', var='pubsub#deliver',
     875                                                 label='Enable delivery?',
     876                                                 value=True))
     877        response = toResponse(iq, 'result')
     878        response.addElement((NS_PUBSUB, 'pubsub'))
     879        response.pubsub.addElement('options')
     880        response.pubsub.options.addChild(form.toElement())
     881        self.stub.send(response)
     882
     883        return d
     884
     885
    703886    def test_setOptions(self):
    704887        """
     
    722905        child = children[0]
    723906        self.assertEqual('test', child['node'])
     907
     908        form = data_form.findForm(child, NS_PUBSUB_SUBSCRIBE_OPTIONS)
     909        self.assertEqual('submit', form.formType)
     910        form.typeCheck({'pubsub#deliver': {'type': 'boolean'}})
     911        self.assertEqual(options, form.getValues())
     912
     913        response = toResponse(iq, 'result')
     914        self.stub.send(response)
     915
     916        return d
     917
     918
     919    def test_setOptionsWithSubscriptionIdentifier(self):
     920        """
     921        setOptions should send out a options-set request with subid.
     922        """
     923        options = {'pubsub#deliver': False}
     924
     925        d = self.protocol.setOptions(JID('pubsub.example.org'), 'test',
     926                                     JID('user@example.org'),
     927                                     options,
     928                                     subscriptionIdentifier='1234',
     929                                     sender=JID('user@example.org'))
     930
     931        iq = self.stub.output[-1]
     932        child = iq.pubsub.options
     933        self.assertEqual('1234', child['subid'])
    724934
    725935        form = data_form.findForm(child, NS_PUBSUB_SUBSCRIBE_OPTIONS)
     
    10041214
    10051215
     1216    def test_fromElementUnsubscribeWithSubscriptionIdentifier(self):
     1217        """
     1218        Test parsing an unsubscription request with subscription identifier.
     1219        """
     1220
     1221        xml = """
     1222        <iq type='set' to='pubsub.example.org'
     1223                       from='user@example.org'>
     1224          <pubsub xmlns='http://jabber.org/protocol/pubsub'>
     1225            <unsubscribe node='test' jid='user@example.org/Home'
     1226                         subid='1234'/>
     1227          </pubsub>
     1228        </iq>
     1229        """
     1230
     1231        request = pubsub.PubSubRequest.fromElement(parseXml(xml))
     1232        self.assertEqual('1234', request.subscriptionIdentifier)
     1233
     1234
    10061235    def test_fromElementUnsubscribeNoJID(self):
    10071236        """
     
    10401269        request = pubsub.PubSubRequest.fromElement(parseXml(xml))
    10411270        self.assertEqual('optionsGet', request.verb)
     1271        self.assertEqual(JID('user@example.org'), request.sender)
     1272        self.assertEqual(JID('pubsub.example.org'), request.recipient)
     1273        self.assertEqual('test', request.nodeIdentifier)
     1274        self.assertEqual(JID('user@example.org/Home'), request.subscriber)
     1275
     1276
     1277    def test_fromElementOptionsGetWithSubscriptionIdentifier(self):
     1278        """
     1279        Test parsing a request for getting subscription options with subid.
     1280        """
     1281
     1282        xml = """
     1283        <iq type='get' to='pubsub.example.org'
     1284                       from='user@example.org'>
     1285          <pubsub xmlns='http://jabber.org/protocol/pubsub'>
     1286            <options node='test' jid='user@example.org/Home'
     1287                     subid='1234'/>
     1288          </pubsub>
     1289        </iq>
     1290        """
     1291
     1292        request = pubsub.PubSubRequest.fromElement(parseXml(xml))
     1293        self.assertEqual('1234', request.subscriptionIdentifier)
    10421294
    10431295
     
    10701322        self.assertEqual(JID('user@example.org/Home'), request.subscriber)
    10711323        self.assertEqual({'pubsub#deliver': '1'}, request.options.getValues())
     1324
     1325
     1326    def test_fromElementOptionsSetWithSubscriptionIdentifier(self):
     1327        """
     1328        Test parsing a request for setting subscription options with subid.
     1329        """
     1330
     1331        xml = """
     1332        <iq type='set' to='pubsub.example.org'
     1333                       from='user@example.org'>
     1334          <pubsub xmlns='http://jabber.org/protocol/pubsub'>
     1335            <options node='test' jid='user@example.org/Home'
     1336                     subid='1234'>
     1337              <x xmlns='jabber:x:data' type='submit'>
     1338                <field var='FORM_TYPE' type='hidden'>
     1339                  <value>http://jabber.org/protocol/pubsub#subscribe_options</value>
     1340                </field>
     1341                <field var='pubsub#deliver'><value>1</value></field>
     1342              </x>
     1343            </options>
     1344          </pubsub>
     1345        </iq>
     1346        """
     1347
     1348        request = pubsub.PubSubRequest.fromElement(parseXml(xml))
     1349        self.assertEqual('1234', request.subscriptionIdentifier)
    10721350
    10731351
     
    15151793        self.assertEqual('test', request.nodeIdentifier)
    15161794        self.assertIdentical(None, request.maxItems)
     1795        self.assertIdentical(None, request.subscriptionIdentifier)
    15171796        self.assertEqual([], request.itemIdentifiers)
     1797
     1798
     1799    def test_fromElementItemsSubscriptionIdentifier(self):
     1800        """
     1801        Test parsing an items request with subscription identifier.
     1802        """
     1803        xml = """
     1804        <iq type='get' to='pubsub.example.org'
     1805                       from='user@example.org'>
     1806          <pubsub xmlns='http://jabber.org/protocol/pubsub'>
     1807            <items node='test' subid='1234'/>
     1808          </pubsub>
     1809        </iq>
     1810        """
     1811
     1812        request = pubsub.PubSubRequest.fromElement(parseXml(xml))
     1813        self.assertEqual('1234', request.subscriptionIdentifier)
    15181814
    15191815
     
    18182114            self.assertEqual(NS_PUBSUB, element.uri)
    18192115            subscription = element.subscription
    1820             self.assertEqual(NS_PUBSUB, subscription.uri)
     2116            self.assertIn(subscription.uri, (None, NS_PUBSUB))
    18212117            self.assertEqual('test', subscription['node'])
    18222118            self.assertEqual('user@example.org/Home', subscription['jid'])
     
    18592155
    18602156
     2157    def test_on_subscribeSubscriptionIdentifier(self):
     2158        """
     2159        If a subscription returns a subid, this should be available.
     2160        """
     2161
     2162        xml = """
     2163        <iq type='set' to='pubsub.example.org'
     2164                       from='user@example.org'>
     2165          <pubsub xmlns='http://jabber.org/protocol/pubsub'>
     2166            <subscribe node='test' jid='user@example.org/Home'/>
     2167          </pubsub>
     2168        </iq>
     2169        """
     2170
     2171        def subscribe(request):
     2172            subscription = pubsub.Subscription(request.nodeIdentifier,
     2173                                               request.subscriber,
     2174                                               'subscribed',
     2175                                               subscriptionIdentifier='1234')
     2176            return defer.succeed(subscription)
     2177
     2178        def cb(element):
     2179            self.assertEqual('1234', element.subscription.getAttribute('subid'))
     2180
     2181        self.resource.subscribe = subscribe
     2182        verify.verifyObject(iwokkel.IPubSubResource, self.resource)
     2183        d = self.handleRequest(xml)
     2184        d.addCallback(cb)
     2185        return d
     2186
     2187
    18612188    def test_on_unsubscribe(self):
    18622189        """
     
    18742201
    18752202        def unsubscribe(request):
     2203            return defer.succeed(None)
     2204
     2205        def cb(element):
     2206            self.assertIdentical(None, element)
     2207
     2208        self.resource.unsubscribe = unsubscribe
     2209        verify.verifyObject(iwokkel.IPubSubResource, self.resource)
     2210        d = self.handleRequest(xml)
     2211        d.addCallback(cb)
     2212        return d
     2213
     2214
     2215    def test_on_unsubscribe(self):
     2216        """
     2217        A successful unsubscription with subid should return an empty response.
     2218        """
     2219
     2220        xml = """
     2221        <iq type='set' to='pubsub.example.org'
     2222                       from='user@example.org'>
     2223          <pubsub xmlns='http://jabber.org/protocol/pubsub'>
     2224            <unsubscribe node='test' jid='user@example.org/Home' subid='1234'/>
     2225          </pubsub>
     2226        </iq>
     2227        """
     2228
     2229        def unsubscribe(request):
     2230            self.assertEqual('1234', request.subscriptionIdentifier)
    18762231            return defer.succeed(None)
    18772232
     
    19722327            subscription = children[0]
    19732328            self.assertEqual('subscription', subscription.name)
    1974             self.assertEqual(NS_PUBSUB, subscription.uri)
     2329            self.assertIn(subscription.uri, (None, NS_PUBSUB))
    19752330            self.assertEqual('user@example.org', subscription['jid'])
    19762331            self.assertEqual('test', subscription['node'])
    19772332            self.assertEqual('subscribed', subscription['subscription'])
     2333
     2334        self.resource.subscriptions = subscriptions
     2335        verify.verifyObject(iwokkel.IPubSubResource, self.resource)
     2336        d = self.handleRequest(xml)
     2337        d.addCallback(cb)
     2338        return d
     2339
     2340
     2341    def test_on_subscriptionsWithSubscriptionIdentifier(self):
     2342        """
     2343        A subscriptions request response should include subids, if set.
     2344        """
     2345
     2346        xml = """
     2347        <iq type='get' to='pubsub.example.org'
     2348                       from='user@example.org'>
     2349          <pubsub xmlns='http://jabber.org/protocol/pubsub'>
     2350            <subscriptions/>
     2351          </pubsub>
     2352        </iq>
     2353        """
     2354
     2355        def subscriptions(request):
     2356            subscription = pubsub.Subscription('test', JID('user@example.org'),
     2357                                               'subscribed',
     2358                                               subscriptionIdentifier='1234')
     2359            return defer.succeed([subscription])
     2360
     2361        def cb(element):
     2362            subscription = element.subscriptions.subscription
     2363            self.assertEqual('1234', subscription['subid'])
    19782364
    19792365        self.resource.subscriptions = subscriptions
Note: See TracChangeset for help on using the changeset viewer.