diff --git a/sleekxmpp/plugins/xep_0004/stanza/field.py b/sleekxmpp/plugins/xep_0004/stanza/field.py index 9bb92311..43293bfd 100644 --- a/sleekxmpp/plugins/xep_0004/stanza/field.py +++ b/sleekxmpp/plugins/xep_0004/stanza/field.py @@ -29,8 +29,19 @@ class FormField(ElementBase): multi_value_types = set(('hidden', 'jid-multi', 'list-multi', 'text-multi')) + def setup(self, xml=None): + if ElementBase.setup(self, xml): + self._type = None + else: + self._type = self['type'] + + def set_type(self, value): + self._set_attr('type', value) + if value: + self._type = value + def add_option(self, label='', value=''): - if self['type'] in self.option_types: + if self._type in self.option_types: opt = FieldOption(parent=self) opt['label'] = label opt['value'] = value @@ -72,15 +83,15 @@ class FormField(ElementBase): valsXML = self.xml.findall('{%s}value' % self.namespace) if len(valsXML) == 0: return None - elif self['type'] == 'boolean': + elif self._type == 'boolean': return valsXML[0].text in self.true_values - elif self['type'] in self.multi_value_types: + elif self._type in self.multi_value_types: values = [] for valXML in valsXML: if valXML.text is None: valXML.text = '' values.append(valXML.text) - if self['type'] == 'text-multi': + if self._type == 'text-multi': values = "\n".join(values) return values else: @@ -113,7 +124,7 @@ class FormField(ElementBase): del self['value'] valXMLName = '{%s}value' % self.namespace - if self['type'] == 'boolean': + if self._type == 'boolean': if value in self.true_values: valXML = ET.Element(valXMLName) valXML.text = '1' @@ -122,14 +133,12 @@ class FormField(ElementBase): valXML = ET.Element(valXMLName) valXML.text = '0' self.xml.append(valXML) - elif self['type'] in self.multi_value_types or not self['type']: + elif self._type in self.multi_value_types or self._type in ('', None): if not isinstance(value, list): - if self['type'] in self.multi_line_types: - value = value.split('\n') - else: - value = [value] + value = value.replace('\r', '') + value = value.split('\n') for val in value: - if self['type'] in ['', None] and val in self.true_values: + if self._type in ('', None) and val in self.true_values: val = '1' valXML = ET.Element(valXMLName) valXML.text = val @@ -137,7 +146,7 @@ class FormField(ElementBase): else: if isinstance(value, list): raise ValueError("Cannot add multiple values " + \ - "to a %s field." % self['type']) + "to a %s field." % self._type) valXML = ET.Element(valXMLName) valXML.text = value self.xml.append(valXML) diff --git a/tests/test_stanza_xep_0004.py b/tests/test_stanza_xep_0004.py index 22f8b77d..e183e5e9 100644 --- a/tests/test_stanza_xep_0004.py +++ b/tests/test_stanza_xep_0004.py @@ -117,4 +117,82 @@ class TestDataForms(SleekTest): """) + def testSubmitType(self): + """Test that setting type to 'submit' clears extra details""" + msg = self.Message() + form = msg['form'] + + fields = OrderedDict() + fields['f1'] = {'type': 'text-single', + 'label': 'Username', + 'required': True} + fields['f2'] = {'type': 'text-private', + 'label': 'Password', + 'required': True} + fields['f3'] = {'type': 'text-multi', + 'label': 'Message', + 'value': 'Enter message.\nA long one even.'} + fields['f4'] = {'type': 'list-single', + 'label': 'Message Type', + 'options': [{'label': 'Cool!', + 'value': 'cool'}, + {'label': 'Urgh!', + 'value': 'urgh'}]} + form['fields'] = fields + + form['type'] = 'submit' + form['values'] = {'f1': 'username', + 'f2': 'hunter2', + 'f3': 'A long\nmultiline\nmessage', + 'f4': 'cool'} + + self.check(form, """ + + + username + + + hunter2 + + + A long + multiline + message + + + cool + + + """, use_values=False) + + def testCancelType(self): + """Test that setting type to 'cancel' clears all fields""" + msg = self.Message() + form = msg['form'] + + fields = OrderedDict() + fields['f1'] = {'type': 'text-single', + 'label': 'Username', + 'required': True} + fields['f2'] = {'type': 'text-private', + 'label': 'Password', + 'required': True} + fields['f3'] = {'type': 'text-multi', + 'label': 'Message', + 'value': 'Enter message.\nA long one even.'} + fields['f4'] = {'type': 'list-single', + 'label': 'Message Type', + 'options': [{'label': 'Cool!', + 'value': 'cool'}, + {'label': 'Urgh!', + 'value': 'urgh'}]} + form['fields'] = fields + + form['type'] = 'cancel' + + self.check(form, """ + + """) + + suite = unittest.TestLoader().loadTestsFromTestCase(TestDataForms)