source: ralphm-patches/pubsub-create-configure.patch @ 21:6e73325a5473

Last change on this file since 21:6e73325a5473 was 21:6e73325a5473, checked in by Ralph Meijer <ralphm@…>, 11 years ago

Split off data forms changes.

File size: 11.2 KB
  • wokkel/pubsub.py

    diff -r d64e96596c50 -r 8425a88d49f5 wokkel/pubsub.py
    a b  
    234234        'optionsSet': ['nodeOrEmpty', 'jid', 'options'],
    235235        'subscriptions': [],
    236236        'affiliations': [],
    237         'create': ['nodeOrNone'],
     237        'create': ['nodeOrNone', 'configureOrNone'],
    238238        'default': ['default'],
    239239        'configureGet': ['nodeOrEmpty'],
    240240        'configureSet': ['nodeOrEmpty', 'configure'],
     
    364364            raise BadRequest(text="Missing configuration form")
    365365
    366366
     367    def _parse_configureOrNone(self, verbElement):
     368        """
     369        Parse optional node configuration form in create request.
     370        """
     371        for element in verbElement.parent.elements():
     372            if element.uri == NS_PUBSUB and element.name == 'configure':
     373                form = data_form.findForm(element, NS_PUBSUB_NODE_CONFIG)
     374                if form:
     375                    if form.formType == 'submit':
     376                        self.options = form
     377                    else:
     378                        raise BadRequest(text="Unexpected form type %r" %
     379                                              form.formType)
     380                else:
     381                    form = data_form.Form('submit',
     382                                          formNamespace=NS_PUBSUB_NODE_CONFIG)
     383                    self.options = form
     384
     385
     386    def _render_configureOrNone(self, verbElement):
     387        """
     388        Render optional node configuration form in create request.
     389        """
     390        if self.options is not None:
     391            configure = verbElement.parent.addElement('configure')
     392            configure.addChild(self.options.toElement())
     393
    367394
    368395    def _parse_itemIdentifiers(self, verbElement):
    369396        """
     
    602629        pass
    603630
    604631
    605     def createNode(self, service, nodeIdentifier=None, sender=None):
     632    def createNode(self, service, nodeIdentifier=None, options=None,
     633                         sender=None):
    606634        """
    607635        Create a publish subscribe node.
    608636
     
    610638        @type service: L{JID}
    611639        @param nodeIdentifier: Optional suggestion for the id of the node.
    612640        @type nodeIdentifier: C{unicode}
     641        @param options: Optional node configuration options.
     642        @type options: C{dict}
    613643        """
    614644        request = PubSubRequest('create')
    615645        request.recipient = service
    616646        request.nodeIdentifier = nodeIdentifier
    617647        request.sender = sender
    618648
     649        if options:
     650            form = data_form.Form(formType='result',
     651                                  formNamespace=NS_PUBSUB_NODE_CONFIG)
     652            form.makeFields(options)
     653            request.options = form
     654
    619655        def cb(iq):
    620656            try:
    621657                new_node = iq.pubsub.create["node"]
     
    887923            d = self.getNodes(requestor, target)
    888924        else:
    889925            d = defer.succeed([])
    890            
    891 
    892926
    893927        d.addCallback(lambda nodes: [disco.DiscoItem(target, node)
    894928                                     for node in nodes])
     
    9981032        form.typeCheck(fieldDefs, filterUnknown=True)
    9991033
    10001034
     1035    def _preProcess_create(self, resource, request):
     1036        if request.options:
     1037            self._checkConfiguration(resource, request.options)
     1038        return request
     1039
     1040
    10011041    def _preProcess_default(self, resource, request):
    10021042        if request.nodeType not in ('leaf', 'collection'):
    10031043            raise error.StanzaError('not-acceptable')
  • wokkel/test/test_pubsub.py

    diff -r d64e96596c50 -r 8425a88d49f5 wokkel/test/test_pubsub.py
    a b  
    1919from wokkel.test.helpers import TestableRequestHandlerMixin, XmlStreamStub
    2020
    2121NS_PUBSUB = 'http://jabber.org/protocol/pubsub'
    22 NS_PUBSUB_CONFIG = 'http://jabber.org/protocol/pubsub#node_config'
     22NS_PUBSUB_NODE_CONFIG = 'http://jabber.org/protocol/pubsub#node_config'
    2323NS_PUBSUB_ERRORS = 'http://jabber.org/protocol/pubsub#errors'
    2424NS_PUBSUB_EVENT = 'http://jabber.org/protocol/pubsub#event'
    2525NS_PUBSUB_OWNER = 'http://jabber.org/protocol/pubsub#owner'
     
    271271        return d
    272272
    273273
     274    def test_createNodeWithConfig(self):
     275        """
     276        Test sending create request with configuration options
     277        """
     278
     279        options = {
     280            'pubsub#title': 'Princely Musings (Atom)',
     281            'pubsub#deliver_payloads': True,
     282            'pubsub#persist_items': '1',
     283            'pubsub#max_items': '10',
     284            'pubsub#access_model': 'open',
     285            'pubsub#type': 'http://www.w3.org/2005/Atom',
     286        }
     287
     288        d = self.protocol.createNode(JID('pubsub.example.org'), 'test',
     289                                     sender=JID('user@example.org'),
     290                                     options=options)
     291
     292        iq = self.stub.output[-1]
     293
     294        # check if there is exactly one configure element
     295        children = list(domish.generateElementsQNamed(iq.pubsub.children,
     296                                                      'configure', NS_PUBSUB))
     297        self.assertEqual(1, len(children))
     298
     299        # check that it has a configuration form
     300        form = data_form.findForm(children[0], NS_PUBSUB_NODE_CONFIG)
     301        self.assertNotIdentical(None, form)
     302
     303        response = toResponse(iq, 'result')
     304        self.stub.send(response)
     305        return d
     306
     307
    274308    def test_deleteNode(self):
    275309        """
    276310        Test sending delete request.
     
    935969        self.assertEqual(JID('user@example.org'), request.sender)
    936970        self.assertEqual(JID('pubsub.example.org'), request.recipient)
    937971        self.assertEqual('mynode', request.nodeIdentifier)
     972        self.assertIdentical(None, request.options)
    938973
    939974
    940975    def test_fromElementCreateInstant(self):
     
    955990        self.assertIdentical(None, request.nodeIdentifier)
    956991
    957992
     993    def test_fromElementCreateConfigureEmpty(self):
     994        """
     995        Test parsing a request to create a node with an empty configuration.
     996        """
     997
     998        xml = """
     999        <iq type='set' to='pubsub.example.org'
     1000                       from='user@example.org'>
     1001          <pubsub xmlns='http://jabber.org/protocol/pubsub'>
     1002            <create node='mynode'/>
     1003            <configure/>
     1004          </pubsub>
     1005        </iq>
     1006        """
     1007
     1008        request = pubsub.PubSubRequest.fromElement(parseXml(xml))
     1009        self.assertEqual({}, request.options.getValues())
     1010
     1011
     1012    def test_fromElementCreateConfigureEmptyWrongOrder(self):
     1013        """
     1014        Test parsing a request to create a node and configure, wrong order.
     1015
     1016        The C{configure} element should come after the C{create} request,
     1017        but we should accept both orders.
     1018        """
     1019
     1020        xml = """
     1021        <iq type='set' to='pubsub.example.org'
     1022                       from='user@example.org'>
     1023          <pubsub xmlns='http://jabber.org/protocol/pubsub'>
     1024            <configure/>
     1025            <create node='mynode'/>
     1026          </pubsub>
     1027        </iq>
     1028        """
     1029
     1030        request = pubsub.PubSubRequest.fromElement(parseXml(xml))
     1031        self.assertEqual({}, request.options.getValues())
     1032
     1033
     1034    def test_fromElementCreateConfigure(self):
     1035        """
     1036        Test parsing a request to create a node.
     1037        """
     1038
     1039        xml = """
     1040        <iq type='set' to='pubsub.example.org'
     1041                       from='user@example.org'>
     1042          <pubsub xmlns='http://jabber.org/protocol/pubsub'>
     1043            <create node='mynode'/>
     1044            <configure>
     1045              <x xmlns='jabber:x:data' type='submit'>
     1046                <field var='FORM_TYPE' type='hidden'>
     1047                  <value>http://jabber.org/protocol/pubsub#node_config</value>
     1048                </field>
     1049                <field var='pubsub#access_model'><value>open</value></field>
     1050                <field var='pubsub#persist_items'><value>0</value></field>
     1051              </x>
     1052            </configure>
     1053          </pubsub>
     1054        </iq>
     1055        """
     1056
     1057        request = pubsub.PubSubRequest.fromElement(parseXml(xml))
     1058        values = request.options.getValues()
     1059        self.assertIn('pubsub#access_model', values)
     1060        self.assertEqual(u'open', values['pubsub#access_model'])
     1061        self.assertIn('pubsub#persist_items', values)
     1062        self.assertEqual(u'0', values['pubsub#persist_items'])
     1063
     1064
    9581065    def test_fromElementDefault(self):
    9591066        """
    9601067        Test parsing a request for the default node configuration.
     
    17411848        return d
    17421849
    17431850
     1851    def test_on_createWithConfig(self):
     1852        """
     1853        On a node create with configuration request the Data Form is parsed and
     1854        L{PubSubResource.create} is called with the passed options.
     1855        """
     1856
     1857        xml = """
     1858        <iq type='set' to='pubsub.example.org'
     1859                       from='user@example.org'>
     1860          <pubsub xmlns='http://jabber.org/protocol/pubsub'>
     1861            <create node='mynode'/>
     1862            <configure>
     1863              <x xmlns='jabber:x:data' type='submit'>
     1864                <field var='FORM_TYPE' type='hidden'>
     1865                  <value>http://jabber.org/protocol/pubsub#node_config</value>
     1866                </field>
     1867                <field var='pubsub#deliver_payloads'><value>0</value></field>
     1868                <field var='pubsub#persist_items'><value>1</value></field>
     1869              </x>
     1870            </configure>
     1871          </pubsub>
     1872        </iq>
     1873        """
     1874
     1875        def getConfigurationOptions():
     1876            return {
     1877                "pubsub#persist_items":
     1878                    {"type": "boolean",
     1879                     "label": "Persist items to storage"},
     1880                "pubsub#deliver_payloads":
     1881                    {"type": "boolean",
     1882                     "label": "Deliver payloads with event notifications"}
     1883                }
     1884
     1885        def create(request):
     1886            self.assertEqual({'pubsub#deliver_payloads': False,
     1887                              'pubsub#persist_items': True},
     1888                             request.options.getValues())
     1889            return defer.succeed(None)
     1890
     1891        self.resource.getConfigurationOptions = getConfigurationOptions
     1892        self.resource.create = create
     1893        verify.verifyObject(iwokkel.IPubSubResource, self.resource)
     1894        return self.handleRequest(xml)
     1895
     1896
    17441897    def test_on_default(self):
    17451898        """
    17461899        A default request should result in
     
    17741927            self.assertEqual(NS_PUBSUB_OWNER, element.uri)
    17751928            self.assertEqual(NS_PUBSUB_OWNER, element.default.uri)
    17761929            form = data_form.Form.fromElement(element.default.x)
    1777             self.assertEqual(NS_PUBSUB_CONFIG, form.formNamespace)
     1930            self.assertEqual(NS_PUBSUB_NODE_CONFIG, form.formNamespace)
    17781931
    17791932        self.resource.getConfigurationOptions = getConfigurationOptions
    17801933        self.resource.default = default
     
    19032056            self.assertEqual(NS_PUBSUB_OWNER, element.uri)
    19042057            self.assertEqual(NS_PUBSUB_OWNER, element.configure.uri)
    19052058            form = data_form.Form.fromElement(element.configure.x)
    1906             self.assertEqual(NS_PUBSUB_CONFIG, form.formNamespace)
     2059            self.assertEqual(NS_PUBSUB_NODE_CONFIG, form.formNamespace)
    19072060            fields = form.fields
    19082061
    19092062            self.assertIn('pubsub#deliver_payloads', fields)
Note: See TracBrowser for help on using the repository browser.