source: ralphm-patches/pubsub-forms.patch @ 22:bb77a1005b63

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

Add bunch of missing tests.

File size: 9.7 KB
  • wokkel/data_form.py

    diff -r 5ccaacff8028 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            elif self.fieldType in ('jid-single', 'jid-multi'):
    257259                value = value.full()
    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
     
    489555
    490556        return form
    491557
     558
    492559    def getValues(self):
     560        """
     561        Extract values from the named form fields.
     562
     563        For all named fields, the corresponding value or values are
     564        returned in a dictionary keyed by the field name. For multi-value
     565        fields, the dictionary value is a list, otherwise a single value.
     566
     567        @rtype: C{dict}
     568        """
    493569        values = {}
    494570
    495571        for name, field in self.fields.iteritems():
     
    501577            values[name] = value
    502578
    503579        return values
     580
     581
     582    def typeCheck(self, fieldDefs, filterUnknown=False):
     583        """
     584        Check values of fields according to the field definition.
     585
     586        This method walks all named fields to check their values against their
     587        type. The field definition in C{fieldDefs} is used to check the field
     588        type. Unknown fields are ignored.
     589
     590        If the field type is C{None} (when not set by the receiving entity),
     591        C{'text-single'} is assumed, as this is the default value.
     592
     593        @param fieldDefs: Field definitions as a dictionary. See
     594            L{wokkel.iwokkel.IPubSubService.getConfigurationOptions}
     595        @type fieldDefs: C{dict}
     596
     597        @param filterUnknown: If C{True}, remove fields that are not in
     598            C{fieldDefs}.
     599        @type filterUnknown: C{bool}
     600        """
     601
     602        filtered = []
     603
     604        for name, field in self.fields.iteritems():
     605            if name in fieldDefs:
     606                if field.fieldType is None:
     607                    field.fieldType = fieldDefs[name]['type']
     608                elif field.fieldType != fieldDefs[name]['type']:
     609                    raise TypeError("Field type for %r is %r, expected %r" %
     610                                    (name,
     611                                     field.fieldType,
     612                                     fieldDefs[name]['type']))
     613                else:
     614                    # Field type is correct
     615                    pass
     616                field.typeCheck()
     617            elif filterUnknown:
     618                filtered.append(field)
     619            else:
     620                # Unknown field, not filtering
     621                pass
     622
     623        for field in filtered:
     624            self.removeField(field)
  • wokkel/pubsub.py

    diff -r 5ccaacff8028 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 5ccaacff8028 wokkel/test/test_data_form.py
    a b  
    544544        field2 = data_form.Field(var='test', value='value2')
    545545        form.addField(field1)
    546546        self.assertRaises(data_form.Error, form.addField, field2)
     547
     548
     549    def test_removeField(self):
     550        """
     551        A removed field should not occur in fieldList.
     552        """
     553        form = data_form.Form('result')
     554        field = data_form.Field('fixed', value='Section 1')
     555        form.addField(field)
     556        form.removeField(field)
     557        self.assertNotIn(field, form.fieldList)
     558
     559
     560    def test_removeFieldNamed(self):
     561        """
     562        A removed named field should not occur in fields.
     563        """
     564        form = data_form.Form('result')
     565        field = data_form.Field(var='test', value='test1')
     566        form.addField(field)
     567        form.removeField(field)
     568        self.assertNotIn('test', form.fields)
     569
     570
     571    def test_makeFieldsJID(self):
     572        values = {'pubsub#creator': jid.JID('user@example.org')}
     573        form = data_form.Form('result')
     574        form.makeFields(values)
     575        field = form.fields['pubsub#creator']
     576        self.assertEqual('jid-single', field.fieldType)
     577
     578
     579    def test_makeFieldsJIDMulti(self):
     580        values = {'pubsub#contact': [jid.JID('user@example.org'),
     581                                     jid.JID('other@example.org')]}
     582        form = data_form.Form('result')
     583        form.makeFields(values)
     584        field = form.fields['pubsub#contact']
     585        self.assertEqual('jid-multi', field.fieldType)
Note: See TracBrowser for help on using the repository browser.