source: ralphm-patches/pubsub-forms.patch @ 24:8116c2eaa96a

Last change on this file since 24:8116c2eaa96a was 24:8116c2eaa96a, checked in by Ralph Meijer <ralphm@…>, 11 years ago

More tests, integrate form-coerce-values.patch.

File size: 9.2 KB
  • wokkel/data_form.py

    diff -r 7ec54fd678fc wokkel/data_form.py
    a b  
    7676            option['label'] = self.label
    7777        return option
    7878
     79
    7980    @staticmethod
    8081    def fromElement(element):
    8182        valueElements = list(domish.generateElementsQNamed(element.children,
     
    212213
    213214        if self.values:
    214215            if (self.fieldType not in ('hidden', 'jid-multi', 'list-multi',
    215                                  'text-multi') and
     216                                       'text-multi') and
    216217                len(self.values) > 1):
    217218                raise TooManyValuesError()
    218219
     
    233234
    234235            self.values = newValues
    235236
     237
    236238    def toElement(self, asForm=False):
    237239        """
    238240        Return the DOM representation of this Field.
     
    256258            else:
    257259                value = unicode(value)
    258260
    259             field.addElement('value', content=value)
     261            field.addElement('value', content=unicode(value))
    260262
    261263        if asForm:
    262264            if self.fieldType in ('list-single', 'list-multi'):
     
    322324
    323325
    324326    @staticmethod
    325     def fromDict(dictionary):
    326         kwargs = dictionary.copy()
     327    def fromDict(fieldDict):
     328        kwargs = fieldDict.copy()
    327329
    328         if 'type' in dictionary:
    329             kwargs['fieldType'] = dictionary['type']
     330        if 'type' in fieldDict:
     331            kwargs['fieldType'] = fieldDict['type']
    330332            del kwargs['type']
    331333
    332         if 'options' in dictionary:
     334        if 'options' in fieldDict:
    333335            options = []
    334             for value, label in dictionary['options'].iteritems():
     336            for value, label in fieldDict['options'].iteritems():
    335337                options.append(Option(value, label))
    336338            kwargs['options'] = options
    337339
     
    415417        """
    416418        Add a field to this form.
    417419
    418         Fields are added in order, and L{fields} is a dictionary of the
     420        Fields are added in order, and C{fields} is a dictionary of the
    419421        named fields, that is kept in sync only if this method is used for
    420422        adding new fields. Multiple fields with the same name are disallowed.
    421423        """
     
    428430        self.fieldList.append(field)
    429431
    430432
     433    def removeField(self, field):
     434        """
     435        Remove a field from this form.
     436        """
     437        self.fieldList.remove(field)
     438
     439        if field.var is not None:
     440            del self.fields[field.var]
     441
     442
     443    def makeFields(self, values, fieldDefs=None, filterUnknown=True):
     444        """
     445        Create fields from values and add them to this form.
     446
     447        This creates fields from a mapping of name to value(s) and adds them to
     448        this form. If C{fieldDefs} is not C{None}, this is used to fill in
     449        additional properties of fields, like the field types, labels and
     450        possible options. If C{filterUnknown} is C{True} and C{fieldDefs} is
     451        not C{None}, fields will only be created from C{values} with a
     452        corresponding entry in C{fieldDefs}.
     453
     454        @param values: Values to create fields from.
     455        @type values: C{dict}
     456
     457        @param fieldDefs: Field definitions as a dictionary. See
     458            L{wokkel.iwokkel.IPubSubService.getConfigurationOptions}
     459        @type fieldDefs: C{dict}
     460
     461        @param filterUnknown: If C{True}, ignore fields that are not in
     462            C{fieldDefs}.
     463        @type filterUnknown: C{bool}
     464        """
     465        for name, value in values.iteritems():
     466            fieldDict = {'var': name}
     467
     468            if fieldDefs is not None:
     469                if name in fieldDefs:
     470                    fieldDict.update(fieldDefs[name])
     471                elif filterUnknown:
     472                    continue
     473
     474            if isinstance(value, list):
     475                fieldDict['values'] = value
     476                if 'type' not in fieldDict:
     477                    if value and hasattr(value[0], 'full'):
     478                        fieldDict['type'] = 'jid-multi'
     479                    else:
     480                        fieldDict['type'] = 'text-multi'
     481            else:
     482                fieldDict['value'] = value
     483                if 'type' not in fieldDict:
     484                    if hasattr(value, 'full'):
     485                        fieldDict['type'] = 'jid-single'
     486                    elif isinstance(value, bool):
     487                        fieldDict['type'] = 'boolean'
     488
     489            self.addField(Field.fromDict(fieldDict))
     490
     491
    431492    def toElement(self):
     493        """
     494        Return the DOM representation of this Form.
     495
     496        @rtype: L{domish.Element}
     497        """
    432498        form = domish.Element((NS_X_DATA, 'x'))
    433499        form['type'] = self.formType
    434500
     
    516582            values[name] = value
    517583
    518584        return values
     585
     586
     587    def typeCheck(self, fieldDefs, filterUnknown=False):
     588        """
     589        Check values of fields according to the field definition.
     590
     591        This method walks all named fields to check their values against their
     592        type. The field definition in C{fieldDefs} is used to check the field
     593        type. Unknown fields are ignored.
     594
     595        If the field type is C{None} (when not set by the receiving entity),
     596        C{'text-single'} is assumed, as this is the default value.
     597
     598        @param fieldDefs: Field definitions as a dictionary. See
     599            L{wokkel.iwokkel.IPubSubService.getConfigurationOptions}
     600        @type fieldDefs: C{dict}
     601
     602        @param filterUnknown: If C{True}, remove fields that are not in
     603            C{fieldDefs}.
     604        @type filterUnknown: C{bool}
     605        """
     606
     607        filtered = []
     608
     609        for name, field in self.fields.iteritems():
     610            if name in fieldDefs:
     611                if field.fieldType is None:
     612                    field.fieldType = fieldDefs[name]['type']
     613                elif field.fieldType != fieldDefs[name]['type']:
     614                    raise TypeError("Field type for %r is %r, expected %r" %
     615                                    (name,
     616                                     field.fieldType,
     617                                     fieldDefs[name]['type']))
     618                else:
     619                    # Field type is correct
     620                    pass
     621                field.typeCheck()
     622            elif filterUnknown:
     623                filtered.append(field)
     624            else:
     625                # Unknown field, not filtering
     626                pass
     627
     628        for field in filtered:
     629            self.removeField(field)
  • wokkel/pubsub.py

    diff -r 7ec54fd678fc wokkel/pubsub.py
    a b  
    10121012            return None
    10131013
    10141014
    1015     def _makeFields(self, options, values):
    1016         fields = []
    1017         for name, value in values.iteritems():
    1018             if name not in options:
    1019                 continue
    1020 
    1021             option = {'var': name}
    1022             option.update(options[name])
    1023             if isinstance(value, list):
    1024                 option['values'] = value
    1025             else:
    1026                 option['value'] = value
    1027             fields.append(data_form.Field.fromDict(option))
    1028         return fields
    1029 
    1030 
    10311015    def _formFromConfiguration(self, resource, values):
    1032         options = resource.getConfigurationOptions()
    1033         fields = self._makeFields(options, values)
     1016        fieldDefs = resource.getConfigurationOptions()
    10341017        form = data_form.Form(formType="form",
    1035                               formNamespace=NS_PUBSUB_NODE_CONFIG,
    1036                               fields=fields)
    1037 
     1018                              formNamespace=NS_PUBSUB_NODE_CONFIG)
     1019        form.makeFields(values, fieldDefs)
    10381020        return form
    10391021
    10401022
  • wokkel/test/test_data_form.py

    diff -r 7ec54fd678fc wokkel/test/test_data_form.py
    a b  
    782782        self.assertRaises(data_form.Error, form.addField, field2)
    783783
    784784
     785    def test_removeField(self):
     786        """
     787        A removed field should not occur in fieldList.
     788        """
     789        form = data_form.Form('result')
     790        field = data_form.Field('fixed', value='Section 1')
     791        form.addField(field)
     792        form.removeField(field)
     793        self.assertNotIn(field, form.fieldList)
     794
     795
     796    def test_removeFieldNamed(self):
     797        """
     798        A removed named field should not occur in fields.
     799        """
     800        form = data_form.Form('result')
     801        field = data_form.Field(var='test', value='test1')
     802        form.addField(field)
     803        form.removeField(field)
     804        self.assertNotIn('test', form.fields)
     805
     806
     807    def test_makeFieldsJID(self):
     808        values = {'pubsub#creator': jid.JID('user@example.org')}
     809        form = data_form.Form('result')
     810        form.makeFields(values)
     811        field = form.fields['pubsub#creator']
     812        self.assertEqual('jid-single', field.fieldType)
     813
     814
     815    def test_makeFieldsJIDMulti(self):
     816        values = {'pubsub#contact': [jid.JID('user@example.org'),
     817                                     jid.JID('other@example.org')]}
     818        form = data_form.Form('result')
     819        form.makeFields(values)
     820        field = form.fields['pubsub#contact']
     821        self.assertEqual('jid-multi', field.fieldType)
     822
     823
    785824    def test_getValues(self):
    786825        """
    787826        Each named field is represented in the values, keyed by name.
Note: See TracBrowser for help on using the repository browser.