Changeset 20:9e1c2535b74e in ralphm-patches


Ignore:
Timestamp:
Dec 30, 2009, 9:10:15 PM (11 years ago)
Author:
Ralph Meijer <ralphm@…>
Branch:
default
Message:

Add filterUnknown for typeCheck, request.options is a form, per docstring.

Files:
2 edited

Legend:

Unmodified
Added
Removed
  • pubsub-create-configure.patch

    r19 r20  
    1 diff -r 9a749c388cda wokkel/data_form.py
    2 --- a/wokkel/data_form.py       Tue Dec 29 14:55:13 2009 +0100
    3 +++ b/wokkel/data_form.py       Tue Dec 29 15:06:54 2009 +0100
     1diff -r 26ba5a2ff579 wokkel/data_form.py
     2--- a/wokkel/data_form.py       Wed Dec 30 17:55:07 2009 +0100
     3+++ b/wokkel/data_form.py       Wed Dec 30 20:46:36 2009 +0100
    44@@ -253,10 +253,10 @@
    55             field['var'] = self.var
     
    1616             field.addElement('value', content=unicode(value))
    1717 
    18 @@ -564,3 +564,25 @@
    19              else:
    20                  # Unknown field, ignoring
    21                  pass
    22 +
     18@@ -616,3 +616,24 @@
     19 
     20         for field in filtered:
     21             self.removeField(field)
    2322+
    2423+
     
    4241+
    4342+    return None
    44 diff -r 9a749c388cda wokkel/pubsub.py
    45 --- a/wokkel/pubsub.py  Tue Dec 29 14:55:13 2009 +0100
    46 +++ b/wokkel/pubsub.py  Tue Dec 29 15:06:54 2009 +0100
     43diff -r 26ba5a2ff579 wokkel/pubsub.py
     44--- a/wokkel/pubsub.py  Wed Dec 30 17:55:07 2009 +0100
     45+++ b/wokkel/pubsub.py  Wed Dec 30 20:46:36 2009 +0100
    4746@@ -234,7 +234,7 @@
    4847         'optionsSet': ['nodeOrEmpty', 'jid', 'options'],
     
    101100+        form = data_form.findForm(verbElement, NS_PUBSUB_NODE_CONFIG)
    102101         if form:
    103              if form.formType == 'submit':
    104                  self.options = form.getValues()
    105 @@ -390,6 +366,46 @@
     102             if form.formType in ('submit', 'cancel'):
     103                 self.options = form
     104@@ -388,6 +364,33 @@
    106105             raise BadRequest(text="Missing configuration form")
    107106 
     
    116115+                if form:
    117116+                    if form.formType == 'submit':
    118 +                        self.options = form.getValues()
     117+                        self.options = form
    119118+                    else:
    120119+                        raise BadRequest(text="Unexpected form type %r" %
    121120+                                              form.formType)
    122121+                else:
    123 +                    self.options = {}
     122+                    form = data_form.Form('submit',
     123+                                          formNamespace=NS_PUBSUB_NODE_CONFIG)
     124+                    self.options = form
    124125+
    125126+
     
    128129+        Render optional node configuration form in create request.
    129130+        """
    130 +        def makeFields(values):
    131 +            fields = []
    132 +            for name, value in values.iteritems():
    133 +                option = {'var': name}
    134 +                if isinstance(value, list):
    135 +                    option['values'] = value
    136 +                else:
    137 +                    option['value'] = value
    138 +                fields.append(data_form.Field.fromDict(option))
    139 +            return fields
    140 +
    141131+        if self.options is not None:
    142 +            fields = makeFields(self.options)
    143 +            form = data_form.Form('submit',
    144 +                                  formNamespace=NS_PUBSUB_NODE_CONFIG,
    145 +                                  fields=fields)
    146132+            configure = verbElement.parent.addElement('configure')
    147 +            configure.addChild(form.toElement())
     133+            configure.addChild(self.options.toElement())
    148134+
    149135 
    150136     def _parse_itemIdentifiers(self, verbElement):
    151137         """
    152 @@ -437,7 +453,7 @@
     138@@ -435,7 +438,7 @@
    153139 
    154140 
     
    157143+        form = data_form.findForm(verbElement, NS_PUBSUB_SUBSCRIBE_OPTIONS)
    158144         if form:
    159              if form.formType == 'submit':
    160                  self.options = form.getValues()
    161 @@ -468,6 +484,7 @@
    162              self._render_options(optionsElement)
    163  
    164  
    165 +
    166      def parseElement(self, element):
    167          """
    168          Parse the publish-subscribe verb and parameters out of a request.
    169 @@ -663,7 +680,8 @@
     145             if form.formType not in ('submit', 'cancel'):
     146                 raise BadRequest(text="Unexpected form type %r" % form.formType)
     147@@ -451,8 +454,8 @@
     148     def _parse_optionsWithSubscribe(self, verbElement):
     149         for element in verbElement.parent.elements():
     150             if element.name == 'options' and element.uri == NS_PUBSUB:
     151-                form = PubSubRequest._findForm(element,
     152-                                               NS_PUBSUB_SUBSCRIBE_OPTIONS)
     153+                form = data_form.findForm(element,
     154+                                          NS_PUBSUB_SUBSCRIBE_OPTIONS)
     155                 if not form:
     156                     continue
     157 
     158@@ -662,7 +665,8 @@
    170159         pass
    171160 
     
    177166         Create a publish subscribe node.
    178167 
    179 @@ -671,11 +689,14 @@
     168@@ -670,12 +674,20 @@
    180169         @type service: L{JID}
    181170         @param nodeIdentifier: Optional suggestion for the id of the node.
     
    188177         request.nodeIdentifier = nodeIdentifier
    189178         request.sender = sender
    190 +        request.options = options
    191  
     179 
     180+        if options:
     181+            form = data_form.Form(formType='result',
     182+                                  formNamespace=NS_PUBSUB_NODE_CONFIG)
     183+            form.makeFields(options)
     184+            request.options = form
     185+
    192186         def cb(iq):
    193187             try:
    194 @@ -952,8 +973,6 @@
     188                 new_node = iq.pubsub.create["node"]
     189@@ -956,8 +968,6 @@
    195190             d = self.getNodes(requestor, target)
    196191         else:
     
    201196         d.addCallback(lambda nodes: [disco.DiscoItem(target, node)
    202197                                      for node in nodes])
    203 @@ -1081,6 +1100,13 @@
    204          return processedValues
     198@@ -1067,6 +1077,12 @@
     199         form.typeCheck(fieldDefs, filterUnknown=True)
    205200 
    206201 
    207202+    def _preProcess_create(self, resource, request):
    208203+        if request.options:
    209 +            request.options = self._checkConfiguration(resource,
    210 +                                                       request.options)
     204+            self._checkConfiguration(resource, request.options)
    211205+        return request
    212206+
     
    215209         if request.nodeType not in ('leaf', 'collection'):
    216210             raise error.StanzaError('not-acceptable')
    217 diff -r 9a749c388cda wokkel/test/test_pubsub.py
    218 --- a/wokkel/test/test_pubsub.py        Tue Dec 29 14:55:13 2009 +0100
    219 +++ b/wokkel/test/test_pubsub.py        Tue Dec 29 15:06:54 2009 +0100
     211diff -r 26ba5a2ff579 wokkel/test/test_pubsub.py
     212--- a/wokkel/test/test_pubsub.py        Wed Dec 30 17:55:07 2009 +0100
     213+++ b/wokkel/test/test_pubsub.py        Wed Dec 30 20:46:36 2009 +0100
    220214@@ -19,7 +19,7 @@
    221215 from wokkel.test.helpers import TestableRequestHandlerMixin, XmlStreamStub
     
    268262         """
    269263         Test sending delete request.
    270 @@ -966,6 +1000,7 @@
     264@@ -998,6 +1032,7 @@
    271265         self.assertEqual(JID('user@example.org'), request.sender)
    272266         self.assertEqual(JID('pubsub.example.org'), request.recipient)
     
    276270 
    277271     def test_fromElementCreateInstant(self):
    278 @@ -986,6 +1021,77 @@
     272@@ -1018,6 +1053,78 @@
    279273         self.assertIdentical(None, request.nodeIdentifier)
    280274 
     
    296290+
    297291+        request = pubsub.PubSubRequest.fromElement(parseXml(xml))
    298 +        self.assertEqual({}, request.options)
     292+        self.assertEqual({}, request.options.getValues())
    299293+
    300294+
     
    318312+
    319313+        request = pubsub.PubSubRequest.fromElement(parseXml(xml))
    320 +        self.assertEqual({}, request.options)
     314+        self.assertEqual({}, request.options.getValues())
    321315+
    322316+
     
    345339+
    346340+        request = pubsub.PubSubRequest.fromElement(parseXml(xml))
    347 +        self.assertIn('pubsub#access_model', request.options)
    348 +        self.assertEqual(u'open', request.options['pubsub#access_model'])
    349 +        self.assertIn('pubsub#persist_items', request.options)
    350 +        self.assertEqual(u'0', request.options['pubsub#persist_items'])
     341+        values = request.options.getValues()
     342+        self.assertIn('pubsub#access_model', values)
     343+        self.assertEqual(u'open', values['pubsub#access_model'])
     344+        self.assertIn('pubsub#persist_items', values)
     345+        self.assertEqual(u'0', values['pubsub#persist_items'])
    351346+
    352347+
     
    354349         """
    355350         Test parsing a request for the default node configuration.
    356 @@ -1771,6 +1877,51 @@
     351@@ -1804,6 +1911,52 @@
    357352         return d
    358353 
     
    394389+        def create(request):
    395390+            self.assertEqual({'pubsub#deliver_payloads': False,
    396 +                              'pubsub#persist_items': True}, request.options)
     391+                              'pubsub#persist_items': True},
     392+                             request.options.getValues())
    397393+            return defer.succeed(None)
    398394+
     
    406402         """
    407403         A default request should result in
    408 @@ -1804,7 +1955,7 @@
     404@@ -1837,7 +1990,7 @@
    409405             self.assertEqual(NS_PUBSUB_OWNER, element.uri)
    410406             self.assertEqual(NS_PUBSUB_OWNER, element.default.uri)
     
    415411         self.resource.getConfigurationOptions = getConfigurationOptions
    416412         self.resource.default = default
    417 @@ -1933,7 +2084,7 @@
     413@@ -1966,7 +2119,7 @@
    418414             self.assertEqual(NS_PUBSUB_OWNER, element.uri)
    419415             self.assertEqual(NS_PUBSUB_OWNER, element.configure.uri)
  • pubsub-subscription-options.patch

    r19 r20  
    1 diff -r 2919e60d3588 wokkel/data_form.py
    2 --- a/wokkel/data_form.py       Mon Dec 28 12:13:34 2009 +0100
    3 +++ b/wokkel/data_form.py       Tue Dec 29 15:34:35 2009 +0100
     1diff -r 3ef9bc7a0d70 wokkel/data_form.py
     2--- a/wokkel/data_form.py       Wed Dec 30 16:53:05 2009 +0100
     3+++ b/wokkel/data_form.py       Wed Dec 30 21:05:59 2009 +0100
    44@@ -76,6 +76,7 @@
    55             option['label'] = self.label
     
    5959             kwargs['options'] = options
    6060 
    61 @@ -416,6 +418,44 @@
     61@@ -343,7 +345,7 @@
     62     """
     63     Data Form.
     64 
     65-    There are two similarly named properties of forms. The L{formType} is the
     66+    There are two similarly named properties of forms. The C{formType} is the
     67     the so-called type of the form, and is set as the C{'type'} attribute
     68     on the form's root element.
     69 
     70@@ -351,19 +353,25 @@
     71     provide a context for the field names used in this form, by setting a
     72     special hidden field named C{'FORM_TYPE'}, to put the names of all
     73     other fields in the namespace of the value of that field. This namespace
     74-    is recorded in the L{formNamespace} instance variable.
     75+    is recorded in the C{formNamespace} instance variable.
     76 
     77     @ivar formType: Type of form. One of C{'form'}, C{'submit'}, {'cancel'},
     78                     or {'result'}.
     79-    @type formType: C{str}.
     80+    @type formType: C{str}
     81+
     82     @ivar formNamespace: The optional namespace of the field names for this
     83-                         form. This goes in the special field named
     84-                         C{'FORM_TYPE'}, if set.
     85-    @type formNamespace: C{str}.
     86-    @ivar fields: Dictionary of fields that have a name. Note that this is
     87-                  meant to be used for reading, only. One should use
     88-                  L{addField} for adding fields.
     89+        form. This goes in the special field named C{'FORM_TYPE'}, if set.
     90+    @type formNamespace: C{str}
     91+
     92+    @ivar fields: Dictionary of named fields. Note that this is meant to be
     93+        used for reading, only. One should use L{addField} or L{makeFields} and
     94+        L{removeField} for adding and removing fields.
     95     @type fields: C{dict}
     96+
     97+    @ivar fieldList: List of all fields, in the order they are added. Like
     98+        C{fields}, this is meant to be used for reading, only.
     99+    @type fieldList: C{list}
     100+
     101     """
     102 
     103     def __init__(self, formType, title=None, instructions=None,
     104@@ -403,7 +411,7 @@
     105         """
     106         Add a field to this form.
     107 
     108-        Fields are added in order, and L{fields} is a dictionary of the
     109+        Fields are added in order, and C{fields} is a dictionary of the
     110         named fields, that is kept in sync only if this method is used for
     111         adding new fields. Multiple fields with the same name are disallowed.
     112         """
     113@@ -416,7 +424,71 @@
    62114         self.fieldList.append(field)
    63115 
    64116 
     117+    def removeField(self, field):
     118+        """
     119+        Remove a field from this form.
     120+        """
     121+        self.fieldList.remove(field)
     122+
     123+        if field.var is not None:
     124+            del self.fields[field.var]
     125+
     126+
    65127+    def makeFields(self, values, fieldDefs=None, filterUnknown=True):
    66128+        """
     
    73135+        not C{None}, fields will only be created from C{values} with a
    74136+        corresponding entry in C{fieldDefs}.
     137+
     138+        @param values: Values to create fields from.
     139+        @type values: C{dict}
     140+
     141+        @param fieldDefs: Field definitions as a dictionary. See
     142+            L{wokkel.iwokkel.IPubSubService.getConfigurationOptions}
     143+        @type fieldDefs: C{dict}
     144+
     145+        @param filterUnknown: If C{True}, ignore fields that are not in
     146+            C{fieldDefs}.
     147+        @type filterUnknown: C{bool}
    75148+        """
    76149+        for name, value in values.iteritems():
     
    102175+
    103176     def toElement(self):
     177+        """
     178+        Return the DOM representation of this Form.
     179+
     180+        @rtype: L{domish.Element}
     181+        """
    104182         form = domish.Element((NS_X_DATA, 'x'))
    105183         form['type'] = self.formType
    106 @@ -489,3 +529,38 @@
     184 
     185@@ -477,7 +549,17 @@
     186 
     187         return form
     188 
     189+
     190     def getValues(self):
     191+        """
     192+        Extract values from the named form fields.
     193+
     194+        For all named fields, the corresponding value or values are
     195+        returned in a dictionary keyed by the field name. For multi-value
     196+        fields, the dictionary value is a list, otherwise a single value.
     197+
     198+        @rtype: C{dict}
     199+        """
     200         values = {}
     201 
     202         for name, field in self.fields.iteritems():
     203@@ -489,3 +571,48 @@
    107204             values[name] = value
    108205 
     
    110207+
    111208+
    112 +    def typeCheck(self, fieldDefs):
     209+    def typeCheck(self, fieldDefs, filterUnknown=False):
    113210+        """
    114211+        Check values of fields according to the field definition.
     
    119216+
    120217+        If the field type is C{None} (when not set by the receiving entity),
    121 +        the field definition is used to set the field's type before checking
    122 +        the values.
     218+        C{'text-single'} is assumed, as this is the default value.
    123219+
    124220+        @param fieldDefs: Field definitions as a dictionary. See
    125221+            L{wokkel.iwokkel.IPubSubService.getConfigurationOptions}
    126 +        @type fieldDefs: C{dict}.
    127 +        """
     222+        @type fieldDefs: C{dict}
     223+
     224+        @param filterUnknown: If C{True}, remove fields that are not in
     225+            C{fieldDefs}.
     226+        @type filterUnknown: C{bool}
     227+        """
     228+
     229+        filtered = []
    128230+
    129231+        for name, field in self.fields.iteritems():
     
    140242+                    pass
    141243+                field.typeCheck()
     244+            elif filterUnknown:
     245+                filtered.append(field)
    142246+            else:
    143 +                # Unknown field, ignoring
     247+                # Unknown field, not filtering
    144248+                pass
    145 diff -r 2919e60d3588 wokkel/pubsub.py
    146 --- a/wokkel/pubsub.py  Mon Dec 28 12:13:34 2009 +0100
    147 +++ b/wokkel/pubsub.py  Tue Dec 29 15:34:35 2009 +0100
     249+
     250+        for field in filtered:
     251+            self.removeField(field)
     252diff -r 3ef9bc7a0d70 wokkel/pubsub.py
     253--- a/wokkel/pubsub.py  Wed Dec 30 16:53:05 2009 +0100
     254+++ b/wokkel/pubsub.py  Wed Dec 30 21:05:59 2009 +0100
    148255@@ -228,7 +228,7 @@
    149256     # Map request verb to parameter handler names
     
    155262         'optionsGet': ['nodeOrEmpty', 'jid'],
    156263         'optionsSet': ['nodeOrEmpty', 'jid', 'options'],
    157 @@ -445,32 +445,71 @@
    158                  self.options = {}
     264@@ -380,10 +380,8 @@
     265         """
     266         form = PubSubRequest._findForm(verbElement, NS_PUBSUB_NODE_CONFIG)
     267         if form:
     268-            if form.formType == 'submit':
     269-                self.options = form.getValues()
     270-            elif form.formType == 'cancel':
     271-                self.options = {}
     272+            if form.formType in ('submit', 'cancel'):
     273+                self.options = form
    159274             else:
    160275                 raise BadRequest(text="Unexpected form type %r" % form.formType)
    161 -        else:
    162 +        elif self.verb == 'optionsSet':
     276         else:
     277@@ -439,38 +437,71 @@
     278     def _parse_options(self, verbElement):
     279         form = PubSubRequest._findForm(verbElement, NS_PUBSUB_SUBSCRIBE_OPTIONS)
     280         if form:
     281-            if form.formType == 'submit':
     282-                self.options = form.getValues()
     283-            elif form.formType == 'cancel':
     284-                self.options = {}
     285-            else:
     286+            if form.formType not in ('submit', 'cancel'):
     287                 raise BadRequest(text="Unexpected form type %r" % form.formType)
     288+            self.options = form
     289         else:
    163290             raise BadRequest(text="Missing options form")
    164291 
     292+
     293+    def _render_options(self, verbElement):
     294+        verbElement.addChild(self.options.toElement())
     295+
    165296+
    166297+    def _parse_optionsWithSubscribe(self, verbElement):
     
    169300+                form = PubSubRequest._findForm(element,
    170301+                                               NS_PUBSUB_SUBSCRIBE_OPTIONS)
    171 +                if form:
    172 +                    self.optionsForm = form
    173 +                    if form.formType == 'submit':
    174 +                        self.options = form.getValues()
    175 +                    else:
    176 +                        BadRequest(text="Unexpected form type %r" % form.formType)
    177 +
    178 +
    179 +    def _render_options(self, verbElement):
    180 +        form = data_form.Form(formType='submit',
    181 +                              formNamespace=NS_PUBSUB_SUBSCRIBE_OPTIONS)
    182 +        form.makeFields(values=self.options)
    183 +        verbElement.addChild(form.toElement())
     302+                if not form:
     303+                    continue
     304+
     305+                self.options = form
     306+                if form.formType != 'submit':
     307+                    BadRequest(text="Unexpected form type %r" % form.formType)
    184308+
    185309+
     
    233357         """
    234358         Send this request to its recipient.
    235 @@ -674,7 +713,8 @@
     359@@ -674,7 +705,8 @@
    236360         return request.send(self.xmlstream)
    237361 
     
    243367         Subscribe to a publish subscribe node.
    244368 
    245 @@ -685,11 +725,14 @@
     369@@ -685,6 +717,8 @@
    246370         @param subscriber: The entity to subscribe to the node. This entity
    247371                            will get notifications of new published items.
     
    252376         request = PubSubRequest('subscribe')
    253377         request.recipient = service
    254          request.nodeIdentifier = nodeIdentifier
     378@@ -692,6 +726,12 @@
    255379         request.subscriber = subscriber
    256 +        request.options = options
    257380         request.sender = sender
    258381 
     382+        if options:
     383+            form = data_form.Form(formType='result',
     384+                                  formNamespace=NS_PUBSUB_SUBSCRIBE_OPTIONS)
     385+            form.makeFields(options)
     386+            request.options = form
     387+
    259388         def cb(iq):
    260 @@ -1012,29 +1055,11 @@
     389             subscription = iq.pubsub.subscription["subscription"]
     390 
     391@@ -956,6 +996,8 @@
     392             handlerName, argNames = self._legacyHandlers[request.verb]
     393             handler = getattr(self, handlerName)
     394             args = [getattr(request, arg) for arg in argNames]
     395+            if 'options' in argNames:
     396+                args[argNames.index('options')] = request.options.getValues()
     397             d = handler(*args)
     398 
     399         # If needed, translate the result into a response
     400@@ -1012,55 +1054,17 @@
    261401             return None
    262402 
     
    291431 
    292432 
    293 diff -r 2919e60d3588 wokkel/test/test_pubsub.py
    294 --- a/wokkel/test/test_pubsub.py        Mon Dec 28 12:13:34 2009 +0100
    295 +++ b/wokkel/test/test_pubsub.py        Tue Dec 29 15:34:35 2009 +0100
     433-    def _checkConfiguration(self, resource, values):
     434-        options = resource.getConfigurationOptions()
     435-        processedValues = {}
     436-
     437-        for key, value in values.iteritems():
     438-            if key not in options:
     439-                continue
     440-
     441-            option = {'var': key}
     442-            option.update(options[key])
     443-            field = data_form.Field.fromDict(option)
     444-            if isinstance(value, list):
     445-                field.values = value
     446-            else:
     447-                field.value = value
     448-            field.typeCheck()
     449-
     450-            if isinstance(value, list):
     451-                processedValues[key] = field.values
     452-            else:
     453-                processedValues[key] = field.value
     454-
     455-        return processedValues
     456+    def _checkConfiguration(self, resource, form):
     457+        fieldDefs = resource.getConfigurationOptions()
     458+        form.typeCheck(fieldDefs, filterUnknown=True)
     459 
     460 
     461     def _preProcess_default(self, resource, request):
     462@@ -1091,12 +1095,11 @@
     463 
     464 
     465     def _preProcess_configureSet(self, resource, request):
     466-        if request.options:
     467-            request.options = self._checkConfiguration(resource,
     468-                                                       request.options)
     469+        if request.options.formType == 'cancel':
     470+            return None
     471+        else:
     472+            self._checkConfiguration(resource, request.options)
     473             return request
     474-        else:
     475-            return None
     476 
     477 
     478     def _toResponse_items(self, result, resource, request):
     479diff -r 3ef9bc7a0d70 wokkel/test/test_pubsub.py
     480--- a/wokkel/test/test_pubsub.py        Wed Dec 30 16:53:05 2009 +0100
     481+++ b/wokkel/test/test_pubsub.py        Wed Dec 30 21:05:59 2009 +0100
    296482@@ -447,6 +447,37 @@
    297483         return d
     
    332518         """
    333519         Test sending subscription request from a specific JID.
    334 @@ -718,6 +749,39 @@
     520@@ -718,6 +749,38 @@
    335521         self.assertEqual(NS_PUBSUB_ERRORS, err.appCondition.uri)
    336522         self.assertEqual('jid-required', err.appCondition.name)
     
    364550+        request = pubsub.PubSubRequest.fromElement(parseXml(xml))
    365551+        self.assertEqual('subscribe', request.verb)
    366 +        request.optionsForm.typeCheck({'pubsub#deliver': {'type': 'boolean'}})
    367 +        request.options = request.optionsForm.getValues()
    368 +        self.assertEqual({'pubsub#deliver': True}, request.options)
     552+        request.options.typeCheck({'pubsub#deliver': {'type': 'boolean'}})
     553+        self.assertEqual({'pubsub#deliver': True}, request.options.getValues())
    369554+
    370555+
     
    372557         """
    373558         Test parsing an unsubscription request.
     559@@ -805,7 +868,7 @@
     560         self.assertEqual(JID('pubsub.example.org'), request.recipient)
     561         self.assertEqual('test', request.nodeIdentifier)
     562         self.assertEqual(JID('user@example.org/Home'), request.subscriber)
     563-        self.assertEqual({'pubsub#deliver': '1'}, request.options)
     564+        self.assertEqual({'pubsub#deliver': '1'}, request.options.getValues())
     565 
     566 
     567     def test_fromElementOptionsSetCancel(self):
     568@@ -825,7 +888,7 @@
     569         """
     570 
     571         request = pubsub.PubSubRequest.fromElement(parseXml(xml))
     572-        self.assertEqual({}, request.options)
     573+        self.assertEqual('cancel', request.options.formType)
     574 
     575 
     576     def test_fromElementOptionsSetBadFormType(self):
     577@@ -1053,7 +1116,8 @@
     578         self.assertEqual(JID('pubsub.example.org'), request.recipient)
     579         self.assertEqual('test', request.nodeIdentifier)
     580         self.assertEqual({'pubsub#deliver_payloads': '0',
     581-                          'pubsub#persist_items': '1'}, request.options)
     582+                          'pubsub#persist_items': '1'},
     583+                         request.options.getValues())
     584 
     585 
     586     def test_fromElementConfigureSetCancel(self):
     587@@ -1073,7 +1137,7 @@
     588         """
     589 
     590         request = pubsub.PubSubRequest.fromElement(parseXml(xml))
     591-        self.assertEqual({}, request.options)
     592+        self.assertEqual('cancel', request.options.formType)
     593 
     594 
     595     def test_fromElementConfigureSetBadFormType(self):
    374596@@ -1895,7 +1959,7 @@
    375597             return defer.succeed({'pubsub#deliver_payloads': '0',
     
    381603         def cb(element):
    382604             self.assertEqual('pubsub', element.name)
     605@@ -1968,7 +2032,8 @@
     606 
     607         def configureSet(request):
     608             self.assertEqual({'pubsub#deliver_payloads': False,
     609-                              'pubsub#persist_items': True}, request.options)
     610+                              'pubsub#persist_items': True},
     611+                             request.options.getValues())
     612             return defer.succeed(None)
     613 
     614         self.resource.getConfigurationOptions = getConfigurationOptions
     615@@ -2040,7 +2105,7 @@
     616 
     617         def configureSet(request):
     618             self.assertEquals(['pubsub#deliver_payloads'],
     619-                              request.options.keys())
     620+                              request.options.fields.keys())
     621 
     622         self.resource.getConfigurationOptions = getConfigurationOptions
     623         self.resource.configureSet = configureSet
     624@@ -2595,6 +2660,48 @@
     625         return d
     626 
     627 
     628+    def test_setConfigurationOptionsDict(self):
     629+        """
     630+        Options should be passed as a dictionary, not a form.
     631+        """
     632+
     633+        xml = """
     634+        <iq type='set' to='pubsub.example.org'
     635+                       from='user@example.org'>
     636+          <pubsub xmlns='http://jabber.org/protocol/pubsub#owner'>
     637+            <configure node='test'>
     638+              <x xmlns='jabber:x:data' type='submit'>
     639+                <field var='FORM_TYPE' type='hidden'>
     640+                  <value>http://jabber.org/protocol/pubsub#node_config</value>
     641+                </field>
     642+                <field var='pubsub#deliver_payloads'><value>0</value></field>
     643+                <field var='pubsub#persist_items'><value>1</value></field>
     644+              </x>
     645+            </configure>
     646+          </pubsub>
     647+        </iq>
     648+        """
     649+
     650+        def getConfigurationOptions():
     651+            return {
     652+                "pubsub#persist_items":
     653+                    {"type": "boolean",
     654+                     "label": "Persist items to storage"},
     655+                "pubsub#deliver_payloads":
     656+                    {"type": "boolean",
     657+                     "label": "Deliver payloads with event notifications"}
     658+                }
     659+
     660+        def setConfiguration(requestor, service, nodeIdentifier, options):
     661+            self.assertEquals({'pubsub#deliver_payloads': False,
     662+                               'pubsub#persist_items': True}, options)
     663+
     664+
     665+        self.service.getConfigurationOptions = getConfigurationOptions
     666+        self.service.setConfiguration = setConfiguration
     667+        return self.handleRequest(xml)
     668+
     669+
     670     def test_items(self):
     671         """
     672         Non-overridden L{PubSubService.items} yields unsupported error.
Note: See TracChangeset for help on using the changeset viewer.