source: wokkel/test/test_data_form.py @ 96:8e6130587088

Last change on this file since 96:8e6130587088 was 96:8e6130587088, checked in by Ralph Meijer <ralphm@…>, 9 years ago

Remove copyright dates from individual source files, only update LICENSE.

  • Property exe set to *
File size: 41.7 KB
Line 
1# Copyright (c) Ralph Meijer.
2# See LICENSE for details.
3
4"""
5Tests for {wokkel.data_form}.
6"""
7
8from twisted.trial import unittest
9from twisted.words.xish import domish
10from twisted.words.protocols.jabber import jid
11
12from wokkel import data_form
13
14NS_X_DATA = 'jabber:x:data'
15
16class OptionTest(unittest.TestCase):
17    """
18    Tests for L{data_form.Option}.
19    """
20
21    def test_toElement(self):
22        """
23        An option is an option element with a value child with the option value.
24        """
25        option = data_form.Option('value')
26        element = option.toElement()
27
28        self.assertEqual('option', element.name)
29        self.assertEqual(NS_X_DATA, element.uri)
30        self.assertEqual(NS_X_DATA, element.value.uri)
31        self.assertEqual('value', unicode(element.value))
32        self.assertFalse(element.hasAttribute('label'))
33
34
35    def test_toElementLabel(self):
36        """
37        A label is rendered as an attribute on the option element.
38        """
39        option = data_form.Option('value', 'label')
40        element = option.toElement()
41
42        self.assertEqual('option', element.name)
43        self.assertEqual(NS_X_DATA, element.uri)
44        self.assertEqual(NS_X_DATA, element.value.uri)
45        self.assertEqual('value', unicode(element.value))
46        self.assertEqual('label', element['label'])
47
48
49    def test_fromElement(self):
50        """
51        An option has a child element with the option value.
52        """
53        element = domish.Element((NS_X_DATA, 'option'))
54        element.addElement('value', content='value')
55        option = data_form.Option.fromElement(element)
56
57        self.assertEqual('value', option.value)
58        self.assertIdentical(None, option.label)
59
60
61    def test_fromElementLabel(self):
62        """
63        An option label is an attribute on the option element.
64        """
65
66        element = domish.Element((NS_X_DATA, 'option'))
67        element.addElement('value', content='value')
68        element['label'] = 'label'
69        option = data_form.Option.fromElement(element)
70
71        self.assertEqual('label', option.label)
72
73
74    def test_fromElementNoValue(self):
75        """
76        An option MUST have a value.
77        """
78        element = domish.Element((NS_X_DATA, 'option'))
79        self.assertRaises(data_form.Error,
80                          data_form.Option.fromElement, element)
81
82
83    def test_repr(self):
84        """
85        The representation of an Option is equal to how it is created.
86        """
87        option = data_form.Option('value', 'label')
88        self.assertEqual("""Option('value', 'label')""", repr(option))
89
90
91
92class FieldTest(unittest.TestCase):
93    """
94    Tests for L{data_form.Field}.
95    """
96
97    def test_basic(self):
98        """
99        Test basic field initialization.
100        """
101        field = data_form.Field(var='test')
102        self.assertEqual('text-single', field.fieldType)
103        self.assertEqual('test', field.var)
104
105
106    def test_labelAndOptions(self):
107        """
108        The label should be set, even if there are options with labels as dict.
109        """
110        field = data_form.Field(label='test',
111                                options={'test2': 'test 2', 'test3': 'test 3'})
112        self.assertEqual('test', field.label)
113
114
115    def test_repr(self):
116        """
117        The repr of a field should be equal to its initialization.
118        """
119        field = data_form.Field('list-single', var='test', label='label',
120                               desc='desc', required=True, value='test',
121                               options=[data_form.Option('test')])
122        self.assertEqual("""Field(fieldType='list-single', """
123                         """var='test', label='label', """
124                         """desc='desc', required=True, """
125                         """values=['test'], """
126                         """options=[Option('test')])""",
127                         repr(field))
128
129
130    def test_toElement(self):
131        """
132        Test rendering to a DOM.
133        """
134        field = data_form.Field(var='test')
135        element = field.toElement()
136
137        self.assertTrue(domish.IElement.providedBy(element))
138        self.assertEquals('field', element.name)
139        self.assertEquals(NS_X_DATA, element.uri)
140        self.assertEquals('text-single',
141                          element.getAttribute('type', 'text-single'))
142        self.assertEquals('test', element['var'])
143        self.assertEquals([], element.children)
144
145
146    def test_toElementTypeNotTextSingle(self):
147        """
148        Always render the field type, if different from text-single.
149        """
150        field = data_form.Field('hidden', var='test')
151        element = field.toElement()
152
153        self.assertEquals('hidden', element.getAttribute('type'))
154
155
156    def test_toElementSingleValue(self):
157        """
158        A single value should yield only one value element.
159        """
160        field = data_form.Field('list-multi', var='test', value='test')
161        element = field.toElement()
162
163        children = list(element.elements())
164        self.assertEqual(1, len(children))
165
166
167    def test_toElementMultipleValues(self):
168        """
169        A field with no type and multiple values should render all values.
170        """
171        field = data_form.Field('list-multi', var='test',
172                                values=['test', 'test2'])
173        element = field.toElement()
174
175        children = list(element.elements())
176        self.assertEqual(2, len(children))
177
178
179    def test_toElementAsForm(self):
180        """
181        Always render the field type, if asForm is True.
182        """
183        field = data_form.Field(var='test')
184        element = field.toElement(True)
185
186        self.assertEquals('text-single', element.getAttribute('type'))
187
188
189    def test_toElementOptions(self):
190        """
191        Test rendering to a DOM with options.
192        """
193        field = data_form.Field('list-single', var='test')
194        field.options = [data_form.Option(u'option1'),
195                         data_form.Option(u'option2')]
196        element = field.toElement(True)
197
198        self.assertEqual(2, len(element.children))
199
200
201    def test_toElementLabel(self):
202        """
203        Test rendering to a DOM with a label.
204        """
205        field = data_form.Field(var='test', label=u'my label')
206        element = field.toElement(True)
207
208        self.assertEqual(u'my label', element.getAttribute('label'))
209
210
211    def test_toElementDescription(self):
212        """
213        Test rendering to a DOM with options.
214        """
215        field = data_form.Field(var='test', desc=u'My desc')
216        element = field.toElement(True)
217
218        self.assertEqual(1, len(element.children))
219        child = element.children[0]
220        self.assertEqual('desc', child.name)
221        self.assertEqual(NS_X_DATA, child.uri)
222        self.assertEqual(u'My desc', unicode(child))
223
224
225    def test_toElementRequired(self):
226        """
227        Test rendering to a DOM with options.
228        """
229        field = data_form.Field(var='test', required=True)
230        element = field.toElement(True)
231
232        self.assertEqual(1, len(element.children))
233        child = element.children[0]
234        self.assertEqual('required', child.name)
235        self.assertEqual(NS_X_DATA, child.uri)
236
237
238    def test_toElementJID(self):
239        """
240        A JID value should render to text.
241        """
242        field = data_form.Field(fieldType='jid-single', var='test',
243                                value=jid.JID(u'test@example.org'))
244        element = field.toElement()
245        self.assertEqual(u'test@example.org', unicode(element.value))
246
247
248    def test_toElementJIDTextSingle(self):
249        """
250        A JID value should render to text if field type is text-single.
251        """
252        field = data_form.Field(fieldType='text-single', var='test',
253                                value=jid.JID(u'test@example.org'))
254        element = field.toElement()
255        self.assertEqual(u'test@example.org', unicode(element.value))
256
257
258    def test_toElementBoolean(self):
259        """
260        A boolean value should render to text.
261        """
262        field = data_form.Field(fieldType='boolean', var='test',
263                                value=True)
264        element = field.toElement()
265        self.assertEqual(u'true', unicode(element.value))
266
267
268    def test_toElementBooleanTextSingle(self):
269        """
270        A boolean value should render to text if the field type is text-single.
271        """
272        field = data_form.Field(var='test', value=True)
273        element = field.toElement()
274        self.assertEqual(u'true', unicode(element.value))
275
276
277    def test_toElementNoType(self):
278        """
279        A field with no type should not have a type attribute.
280        """
281        field = data_form.Field(None, var='test', value='test')
282        element = field.toElement()
283        self.assertFalse(element.hasAttribute('type'))
284
285
286    def test_toElementNoTypeMultipleValues(self):
287        """
288        A field with no type and multiple values should render all values.
289        """
290        field = data_form.Field(None, var='test', values=['test', 'test2'])
291        element = field.toElement()
292
293        self.assertFalse(element.hasAttribute('type'))
294        children = list(element.elements())
295        self.assertEqual(2, len(children))
296
297
298    def test_typeCheckNoFieldName(self):
299        """
300        A field not of type fixed must have a var.
301        """
302        field = data_form.Field(fieldType='list-single')
303        self.assertRaises(data_form.FieldNameRequiredError, field.typeCheck)
304
305
306    def test_typeCheckTooManyValues(self):
307        """
308        Expect an exception if too many values are set, depending on type.
309        """
310        field = data_form.Field(fieldType='list-single', var='test',
311                                values=[u'value1', u'value2'])
312        self.assertRaises(data_form.TooManyValuesError, field.typeCheck)
313
314
315    def test_typeCheckBooleanFalse(self):
316        """
317        Test possible False values for a boolean field.
318        """
319        field = data_form.Field(fieldType='boolean', var='test')
320
321        for value in (False, 0, '0', 'false', 'False', []):
322            field.value = value
323            field.typeCheck()
324            self.assertIsInstance(field.value, bool)
325            self.assertFalse(field.value)
326
327
328    def test_typeCheckBooleanTrue(self):
329        """
330        Test possible True values for a boolean field.
331        """
332        field = data_form.Field(fieldType='boolean', var='test')
333
334        for value in (True, 1, '1', 'true', 'True', ['test']):
335            field.value = value
336            field.typeCheck()
337            self.assertIsInstance(field.value, bool)
338            self.assertTrue(field.value)
339
340
341    def test_typeCheckBooleanBad(self):
342        """
343        A bad value for a boolean field should raise a ValueError
344        """
345        field = data_form.Field(fieldType='boolean', var='test')
346        field.value = 'test'
347        self.assertRaises(ValueError, field.typeCheck)
348
349
350    def test_typeCheckJID(self):
351        """
352        The value of jid field should be a JID or coercable to one.
353        """
354        field = data_form.Field(fieldType='jid-single', var='test',
355                                value=jid.JID('test@example.org'))
356        field.typeCheck()
357
358
359    def test_typeCheckJIDString(self):
360        """
361        The string value of jid field should be coercable into a JID.
362        """
363        field = data_form.Field(fieldType='jid-single', var='test',
364                                value='test@example.org')
365        field.typeCheck()
366        self.assertEquals(jid.JID(u'test@example.org'), field.value)
367
368
369    def test_typeCheckJIDBad(self):
370        """
371        An invalid JID string should raise an exception.
372        """
373        field = data_form.Field(fieldType='jid-single', var='test',
374                                value='test@@example.org')
375        self.assertRaises(jid.InvalidFormat, field.typeCheck)
376
377
378    def test_fromElementType(self):
379        element = domish.Element((NS_X_DATA, 'field'))
380        element['type'] = 'fixed'
381        field = data_form.Field.fromElement(element)
382        self.assertEquals('fixed', field.fieldType)
383
384
385    def test_fromElementNoType(self):
386        element = domish.Element((NS_X_DATA, 'field'))
387        field = data_form.Field.fromElement(element)
388        self.assertEquals(None, field.fieldType)
389
390
391    def test_fromElementValueTextSingle(self):
392        """
393        Parsed text-single field values should be of type C{unicode}.
394        """
395        element = domish.Element((NS_X_DATA, 'field'))
396        element['type'] = 'text-single'
397        element.addElement('value', content=u'text')
398        field = data_form.Field.fromElement(element)
399        self.assertEquals('text', field.value)
400
401
402    def test_fromElementValueJID(self):
403        """
404        Parsed jid-single field values should be of type C{unicode}.
405        """
406        element = domish.Element((NS_X_DATA, 'field'))
407        element['type'] = 'jid-single'
408        element.addElement('value', content=u'user@example.org')
409        field = data_form.Field.fromElement(element)
410        self.assertEquals(u'user@example.org', field.value)
411
412
413    def test_fromElementValueJIDMalformed(self):
414        """
415        Parsed jid-single field values should be of type C{unicode}.
416
417        No validation should be done at this point, so invalid JIDs should
418        also be passed as-is.
419        """
420        element = domish.Element((NS_X_DATA, 'field'))
421        element['type'] = 'jid-single'
422        element.addElement('value', content=u'@@')
423        field = data_form.Field.fromElement(element)
424        self.assertEquals(u'@@', field.value)
425
426
427    def test_fromElementValueBoolean(self):
428        """
429        Parsed boolean field values should be of type C{unicode}.
430        """
431        element = domish.Element((NS_X_DATA, 'field'))
432        element['type'] = 'boolean'
433        element.addElement('value', content=u'false')
434        field = data_form.Field.fromElement(element)
435        self.assertEquals(u'false', field.value)
436
437
438    def test_fromElementDesc(self):
439        """
440        Field descriptions are in a desc child element.
441        """
442        element = domish.Element((NS_X_DATA, 'field'))
443        element.addElement('desc', content=u'My description')
444        field = data_form.Field.fromElement(element)
445        self.assertEqual(u'My description', field.desc)
446
447
448    def test_fromElementOption(self):
449        """
450        Field descriptions are in a desc child element.
451        """
452        element = domish.Element((NS_X_DATA, 'field'))
453        element.addElement('option').addElement('value', content=u'option1')
454        element.addElement('option').addElement('value', content=u'option2')
455        field = data_form.Field.fromElement(element)
456        self.assertEqual(2, len(field.options))
457
458
459    def test_fromElementRequired(self):
460        """
461        Required fields have a required child element.
462        """
463        element = domish.Element((NS_X_DATA, 'field'))
464        element.addElement('required')
465        field = data_form.Field.fromElement(element)
466        self.assertTrue(field.required)
467
468
469    def test_fromElementChildOtherNamespace(self):
470        """
471        Child elements from another namespace are ignored.
472        """
473        element = domish.Element((NS_X_DATA, 'field'))
474        element['var'] = 'test'
475        child = element.addElement(('myns', 'value'))
476        field = data_form.Field.fromElement(element)
477
478        self.assertIdentical(None, field.value)
479
480
481    def test_fromDict(self):
482        """
483        A named field with a value can be created by providing a dictionary.
484        """
485        fieldDict = {'var': 'test', 'value': 'text'}
486        field = data_form.Field.fromDict(fieldDict)
487        self.assertEqual('test', field.var)
488        self.assertEqual('text', field.value)
489
490
491    def test_fromDictFieldType(self):
492        """
493        The field type is set using the key 'type'.
494        """
495        fieldDict = {'type': 'boolean'}
496        field = data_form.Field.fromDict(fieldDict)
497        self.assertEqual('boolean', field.fieldType)
498
499
500    def test_fromDictOptions(self):
501        """
502        The field options are set using the key 'options'.
503
504        The options are represented as a dictionary keyed by option,
505        with the optional label as value.
506        """
507        fieldDict = {'options': {'value1': 'label1',
508                                 'value2': 'label2'}}
509        field = data_form.Field.fromDict(fieldDict)
510        self.assertEqual(2, len(field.options))
511        options = {}
512        for option in field.options:
513            options[option.value] = option.label
514
515        self.assertEqual(options, fieldDict['options'])
516
517
518class FormTest(unittest.TestCase):
519    """
520    Tests for L{data_form.Form}.
521    """
522
523    def test_formType(self):
524        """
525        A form has a type.
526        """
527
528        form = data_form.Form('result')
529        self.assertEqual('result', form.formType)
530
531
532    def test_toElement(self):
533        """
534        The toElement method returns a form's DOM representation.
535        """
536        form = data_form.Form('result')
537        element = form.toElement()
538
539        self.assertTrue(domish.IElement.providedBy(element))
540        self.assertEquals('x', element.name)
541        self.assertEquals(NS_X_DATA, element.uri)
542        self.assertEquals('result', element['type'])
543        self.assertEquals([], element.children)
544
545
546    def test_toElementTitle(self):
547        """
548        A title is rendered as a child element with the title as CDATA.
549        """
550        form = data_form.Form('form', title='Bot configuration')
551        element = form.toElement()
552
553        elements = list(element.elements())
554        self.assertEqual(1, len(elements))
555        title = elements[0]
556        self.assertEqual('title', title.name)
557        self.assertEqual(NS_X_DATA, title.uri)
558        self.assertEqual('Bot configuration', unicode(title))
559
560
561    def test_toElementInstructions(self):
562        """
563        Instructions are rendered as child elements with CDATA.
564        """
565        form = data_form.Form('form', instructions=['Fill out this form!'])
566        element = form.toElement()
567
568        elements = list(element.elements())
569        self.assertEqual(1, len(elements))
570        instructions = elements[0]
571        self.assertEqual('instructions', instructions.name)
572        self.assertEqual(NS_X_DATA, instructions.uri)
573        self.assertEqual('Fill out this form!', unicode(instructions))
574
575
576    def test_toElementInstructionsMultiple(self):
577        """
578        Instructions render as one element per instruction, in order.
579        """
580        form = data_form.Form('form', instructions=['Fill out this form!',
581                                                    'no really'])
582        element = form.toElement()
583
584        elements = list(element.elements())
585        self.assertEqual(2, len(elements))
586        instructions1 = elements[0]
587        instructions2 = elements[1]
588        self.assertEqual('instructions', instructions1.name)
589        self.assertEqual(NS_X_DATA, instructions1.uri)
590        self.assertEqual('Fill out this form!', unicode(instructions1))
591        self.assertEqual('instructions', instructions2.name)
592        self.assertEqual(NS_X_DATA, instructions2.uri)
593        self.assertEqual('no really', unicode(instructions2))
594
595
596    def test_toElementFormType(self):
597        """
598        The form type is rendered as a hidden field with name FORM_TYPE.
599        """
600        form = data_form.Form('form', formNamespace='jabber:bot')
601        element = form.toElement()
602
603        elements = list(element.elements())
604        self.assertEqual(1, len(elements))
605        formTypeField = elements[0]
606        self.assertEqual('field', formTypeField.name)
607        self.assertEqual(NS_X_DATA, formTypeField.uri)
608        self.assertEqual('FORM_TYPE', formTypeField['var'])
609        self.assertEqual('hidden', formTypeField['type'])
610        self.assertEqual('jabber:bot', unicode(formTypeField.value))
611
612
613    def test_toElementFields(self):
614        """
615        Fields are rendered as child elements, in order.
616        """
617        fields = [data_form.Field('fixed', value='Section 1'),
618                  data_form.Field('text-single',
619                                  var='botname',
620                                  label='The name of your bot'),
621                  data_form.Field('text-multi',
622                                  var='description',
623                                  label='Helpful description of your bot'),
624                  data_form.Field('boolean',
625                                  var='public',
626                                  label='Public bot?',
627                                  required=True)
628                 ]
629        form = data_form.Form('form', fields=fields)
630        element = form.toElement()
631
632        elements = list(element.elements())
633        self.assertEqual(4, len(elements))
634        for field in elements:
635            self.assertEqual('field', field.name)
636            self.assertEqual(NS_X_DATA, field.uri)
637
638        # Check order
639        self.assertEqual('fixed', elements[0]['type'])
640        self.assertEqual('botname', elements[1]['var'])
641        self.assertEqual('description', elements[2]['var'])
642        self.assertEqual('public', elements[3]['var'])
643
644
645    def test_fromElement(self):
646        """
647        C{fromElement} creates a L{data_form.Form} from a DOM representation.
648        """
649        element = domish.Element((NS_X_DATA, 'x'))
650        element['type'] = 'result'
651        form = data_form.Form.fromElement(element)
652
653        self.assertEquals('result', form.formType)
654        self.assertEquals(None, form.title)
655        self.assertEquals([], form.instructions)
656        self.assertEquals({}, form.fields)
657
658
659    def test_fromElementInvalidElementName(self):
660        """
661        Bail if the passed element does not have the correct name.
662        """
663        element = domish.Element((NS_X_DATA, 'form'))
664        self.assertRaises(Exception, data_form.Form.fromElement, element)
665
666
667    def test_fromElementInvalidElementURI(self):
668        """
669        Bail if the passed element does not have the correct namespace.
670        """
671        element = domish.Element(('myns', 'x'))
672        self.assertRaises(Exception, data_form.Form.fromElement, element)
673
674
675    def test_fromElementTitle(self):
676        element = domish.Element((NS_X_DATA, 'x'))
677        element.addElement('title', content='My title')
678        form = data_form.Form.fromElement(element)
679
680        self.assertEquals('My title', form.title)
681
682
683    def test_fromElementInstructions(self):
684        element = domish.Element((NS_X_DATA, 'x'))
685        element.addElement('instructions', content='instruction')
686        form = data_form.Form.fromElement(element)
687
688        self.assertEquals(['instruction'], form.instructions)
689
690
691    def test_fromElementInstructions2(self):
692        element = domish.Element((NS_X_DATA, 'x'))
693        element.addElement('instructions', content='instruction 1')
694        element.addElement('instructions', content='instruction 2')
695        form = data_form.Form.fromElement(element)
696
697        self.assertEquals(['instruction 1', 'instruction 2'], form.instructions)
698
699
700    def test_fromElementOneField(self):
701        element = domish.Element((NS_X_DATA, 'x'))
702        element.addElement('field')
703        form = data_form.Form.fromElement(element)
704
705        self.assertEquals(1, len(form.fieldList))
706        self.assertNotIn('field', form.fields)
707
708
709    def test_fromElementTwoFields(self):
710        element = domish.Element((NS_X_DATA, 'x'))
711        element.addElement('field')['var'] = 'field1'
712        element.addElement('field')['var'] = 'field2'
713        form = data_form.Form.fromElement(element)
714
715        self.assertEquals(2, len(form.fieldList))
716        self.assertIn('field1', form.fields)
717        self.assertEquals('field1', form.fieldList[0].var)
718        self.assertIn('field2', form.fields)
719        self.assertEquals('field2', form.fieldList[1].var)
720
721
722    def test_fromElementFormType(self):
723        """
724        The form type is a hidden field named FORM_TYPE.
725        """
726        element = domish.Element((NS_X_DATA, 'x'))
727        field = element.addElement('field')
728        field['var'] = 'FORM_TYPE'
729        field['type'] = 'hidden'
730        field.addElement('value', content='myns')
731        form = data_form.Form.fromElement(element)
732
733        self.assertNotIn('FORM_TYPE', form.fields)
734        self.assertEqual('myns', form.formNamespace)
735
736    def test_fromElementFormTypeNotHidden(self):
737        """
738        A non-hidden field named FORM_TYPE does not set the form type.
739        """
740        element = domish.Element((NS_X_DATA, 'x'))
741        field = element.addElement('field')
742        field['var'] = 'FORM_TYPE'
743        field.addElement('value', content='myns')
744        form = data_form.Form.fromElement(element)
745
746        self.assertIn('FORM_TYPE', form.fields)
747        self.assertIdentical(None, form.formNamespace)
748
749
750    def test_fromElementChildOtherNamespace(self):
751        """
752        Child elements from another namespace are ignored.
753        """
754        element = domish.Element((NS_X_DATA, 'x'))
755        element['type'] = 'result'
756        field = element.addElement(('myns', 'field'))
757        field['var'] = 'test'
758        form = data_form.Form.fromElement(element)
759
760        self.assertEqual(0, len(form.fields))
761
762
763    def test_repr(self):
764        """
765        The repr of a form should be equal to its initialization.
766        """
767        form = data_form.Form('form', title='title', instructions=['instr'],
768                                      formNamespace='myns',
769                                      fields=[data_form.Field('fixed',
770                                                              value='test')])
771        self.assertEqual("""Form(formType='form', title='title', """
772                         """instructions=['instr'], formNamespace='myns', """
773                         """fields=[Field(fieldType='fixed', """
774                         """values=['test'])])""",
775                         repr(form))
776
777
778    def test_addField(self):
779        """
780        A field should occur in fieldList.
781        """
782        form = data_form.Form('result')
783        field = data_form.Field('fixed', value='Section 1')
784        form.addField(field)
785        self.assertEqual([field], form.fieldList)
786
787
788    def test_addFieldTwice(self):
789        """
790        Fields occur in fieldList in the order they were added.
791        """
792        form = data_form.Form('result')
793        field1 = data_form.Field('fixed', value='Section 1')
794        field2 = data_form.Field('fixed', value='Section 2')
795        form.addField(field1)
796        form.addField(field2)
797        self.assertEqual([field1, field2], form.fieldList)
798
799
800    def test_addFieldNotNamed(self):
801        """
802        A non-named field should not occur in fields.
803        """
804        form = data_form.Form('result')
805        field = data_form.Field('fixed', value='Section 1')
806        form.addField(field)
807        self.assertEqual({}, form.fields)
808
809
810    def test_addFieldNamed(self):
811        """
812        A named field should occur in fields.
813        """
814        form = data_form.Form('result')
815        field = data_form.Field(var='test')
816        form.addField(field)
817        self.assertEqual({'test': field}, form.fields)
818
819
820    def test_addFieldTwiceNamed(self):
821        """
822        A second named field should occur in fields.
823        """
824        form = data_form.Form('result')
825        field1 = data_form.Field(var='test')
826        field2 = data_form.Field(var='test2')
827        form.addField(field2)
828        form.addField(field1)
829        self.assertEqual({'test': field1, 'test2': field2}, form.fields)
830
831
832    def test_addFieldSameName(self):
833        """
834        A named field cannot occur twice.
835        """
836        form = data_form.Form('result')
837        field1 = data_form.Field(var='test', value='value')
838        field2 = data_form.Field(var='test', value='value2')
839        form.addField(field1)
840        self.assertRaises(data_form.Error, form.addField, field2)
841
842
843    def test_removeField(self):
844        """
845        A removed field should not occur in fieldList.
846        """
847        form = data_form.Form('result')
848        field = data_form.Field('fixed', value='Section 1')
849        form.addField(field)
850        form.removeField(field)
851        self.assertNotIn(field, form.fieldList)
852
853
854    def test_removeFieldNamed(self):
855        """
856        A removed named field should not occur in fields.
857        """
858        form = data_form.Form('result')
859        field = data_form.Field(var='test', value='test1')
860        form.addField(field)
861        form.removeField(field)
862        self.assertNotIn('test', form.fields)
863
864
865    def test_makeField(self):
866        """
867        Fields can be created from a dict of values and a dict of field defs.
868        """
869        fieldDefs = {
870                "pubsub#persist_items":
871                    {"type": "boolean",
872                     "label": "Persist items to storage"},
873                "pubsub#deliver_payloads":
874                    {"type": "boolean",
875                     "label": "Deliver payloads with event notifications"},
876                "pubsub#creator":
877                    {"type": "jid-single",
878                     "label": "The JID of the node creator"},
879                "pubsub#description":
880                    {"type": "text-single",
881                     "label": "A description of the node"},
882                "pubsub#owner":
883                    {"type": "jid-single",
884                     "label": "Owner of the node"},
885                }
886        values = {'pubsub#deliver_payloads': '0',
887                  'pubsub#persist_items': True,
888                  'pubsub#description': 'a great node',
889                  'pubsub#owner': jid.JID('user@example.org'),
890                  'x-myfield': ['a', 'b']}
891
892        form = data_form.Form('submit')
893        form.makeFields(values, fieldDefs)
894
895        # Check that the expected fields have been created
896        self.assertIn('pubsub#deliver_payloads', form.fields)
897        self.assertIn('pubsub#persist_items', form.fields)
898        self.assertIn('pubsub#description', form.fields)
899        self.assertIn('pubsub#owner', form.fields)
900
901        # This field is not created because there is no value for it.
902        self.assertNotIn('pubsub#creator', form.fields)
903
904        # This field is not created because it does not appear in fieldDefs
905        # and filterUnknown defaults to True
906        self.assertNotIn('x-myfield', form.fields)
907
908        # Check properties the created fields
909        self.assertEqual('boolean',
910                         form.fields['pubsub#deliver_payloads'].fieldType)
911        self.assertEqual('0',
912                         form.fields['pubsub#deliver_payloads'].value)
913        self.assertEqual('Deliver payloads with event notifications',
914                         form.fields['pubsub#deliver_payloads'].label)
915        self.assertEqual(True,
916                         form.fields['pubsub#persist_items'].value)
917
918
919    def test_makeFieldNotFilterUnknown(self):
920        """
921        Fields can be created from a dict of values and a dict of field defs.
922        """
923        fieldDefs = {
924                "pubsub#persist_items":
925                    {"type": "boolean",
926                     "label": "Persist items to storage"},
927                }
928        values = {'x-myfield': ['a', 'b']}
929
930        form = data_form.Form('submit')
931        form.makeFields(values, fieldDefs, filterUnknown=False)
932
933        field = form.fields['x-myfield']
934        self.assertEqual(None, field.fieldType)
935        self.assertEqual(values, form.getValues())
936
937
938    def test_makeFieldsUnknownTypeJID(self):
939        """
940        Without type, a single JID value sets field type jid-single.
941        """
942        values = {'pubsub#creator': jid.JID('user@example.org')}
943        form = data_form.Form('result')
944        form.makeFields(values)
945
946        field = form.fields['pubsub#creator']
947        self.assertEqual(None, field.fieldType)
948        self.assertEqual(values, form.getValues())
949
950
951    def test_makeFieldsUnknownTypeJIDMulti(self):
952        """
953        Without type, multiple JID values sets field type jid-multi.
954        """
955        values = {'pubsub#contact': [jid.JID('user@example.org'),
956                                     jid.JID('other@example.org')]}
957        form = data_form.Form('result')
958        form.makeFields(values)
959
960        field = form.fields['pubsub#contact']
961        self.assertEqual(None, field.fieldType)
962        self.assertEqual(values, form.getValues())
963
964
965    def test_makeFieldsUnknownTypeBoolean(self):
966        """
967        Without type, a boolean value sets field type boolean.
968        """
969        values = {'pubsub#persist_items': True}
970        form = data_form.Form('result')
971        form.makeFields(values)
972
973        field = form.fields['pubsub#persist_items']
974        self.assertEqual(None, field.fieldType)
975        self.assertEqual(values, form.getValues())
976
977
978    def test_makeFieldsUnknownTypeListMulti(self):
979        """
980        Without type, multiple values sets field type list-multi.
981        """
982        values = {'pubsub#show-values': ['chat', 'online', 'away']}
983        form = data_form.Form('result')
984        form.makeFields(values)
985
986        field = form.fields['pubsub#show-values']
987        self.assertEqual(None, field.fieldType)
988        self.assertEqual(values, form.getValues())
989
990
991    def test_getValues(self):
992        """
993        Each named field is represented in the values, keyed by name.
994        """
995        fields = [data_form.Field(var='botname', value='The Jabber Bot'),
996                  data_form.Field('boolean', var='public', value=True),
997                  data_form.Field('list-multi', var='features',
998                                                values=['news', 'search'])]
999        form = data_form.Form('submit', fields=fields)
1000        values = form.getValues()
1001        self.assertEqual({'botname': 'The Jabber Bot',
1002                          'public': True,
1003                          'features': ['news', 'search']},
1004                         values)
1005
1006
1007    def test_getValuesOneValueTypeMulti(self):
1008        """
1009        A single value for a multi-value field type is returned in a list.
1010        """
1011        fields = [data_form.Field('list-multi', var='features',
1012                                                values=['news'])]
1013        form = data_form.Form('submit', fields=fields)
1014        values = form.getValues()
1015        self.assertEqual({'features': ['news']}, values)
1016
1017
1018    def test_getValuesMultipleValuesNoType(self):
1019        """
1020        Multiple values for a field without type are returned in a list.
1021        """
1022        fields = [data_form.Field(None, var='features',
1023                                        values=['news', 'search'])]
1024        form = data_form.Form('submit', fields=fields)
1025        values = form.getValues()
1026        self.assertEqual({'features': ['news', 'search']}, values)
1027
1028
1029    def test_getValuesMultipleValuesTypeSingle(self):
1030        """
1031        Multiple values for a single-value field type returns the first value.
1032        """
1033        fields = [data_form.Field('text-single', var='features',
1034                                        values=['news', 'search'])]
1035        form = data_form.Form('submit', fields=fields)
1036        values = form.getValues()
1037        self.assertEqual({'features': 'news'}, values)
1038
1039
1040    def test_typeCheckKnownFieldChecked(self):
1041        """
1042        Known fields are type checked.
1043        """
1044        checked = []
1045        fieldDefs = {"pubsub#description":
1046                        {"type": "text-single",
1047                         "label": "A description of the node"}}
1048        form = data_form.Form('submit')
1049        form.addField(data_form.Field(var='pubsub#description',
1050                                      value='a node'))
1051        field = form.fields['pubsub#description']
1052        field.typeCheck = lambda : checked.append(None)
1053        form.typeCheck(fieldDefs)
1054
1055        self.assertEqual([None], checked)
1056
1057
1058    def test_typeCheckKnownFieldNoType(self):
1059        """
1060        Known fields without a type get the type of the field definition.
1061        """
1062        checked = []
1063        fieldDefs = {"pubsub#description":
1064                        {"type": "text-single",
1065                         "label": "A description of the node"}}
1066        form = data_form.Form('submit')
1067        form.addField(data_form.Field(None, var='pubsub#description',
1068                                            value='a node'))
1069        field = form.fields['pubsub#description']
1070        field.typeCheck = lambda : checked.append(None)
1071        form.typeCheck(fieldDefs)
1072
1073        self.assertEqual('text-single', field.fieldType)
1074        self.assertEqual([None], checked)
1075
1076
1077    def test_typeCheckWrongFieldType(self):
1078        """
1079        A field should have the same type as the field definition.
1080        """
1081        checked = []
1082        fieldDefs = {"pubsub#description":
1083                        {"type": "text-single",
1084                         "label": "A description of the node"}}
1085        form = data_form.Form('submit')
1086        form.addField(data_form.Field('list-single', var='pubsub#description',
1087                                                     value='a node'))
1088        field = form.fields['pubsub#description']
1089        field.typeCheck = lambda : checked.append(None)
1090
1091        self.assertRaises(TypeError, form.typeCheck, fieldDefs)
1092        self.assertEqual([], checked)
1093
1094
1095    def test_typeCheckDefaultTextSingle(self):
1096        """
1097        If a field definition has no type, use text-single.
1098        """
1099        checked = []
1100        fieldDefs = {"pubsub#description":
1101                        {"label": "A description of the node"}}
1102        form = data_form.Form('submit')
1103        form.addField(data_form.Field('text-single', var='pubsub#description',
1104                                                     value='a node'))
1105        field = form.fields['pubsub#description']
1106        field.typeCheck = lambda : checked.append(None)
1107        form.typeCheck(fieldDefs)
1108
1109        self.assertEqual([None], checked)
1110
1111
1112    def test_typeCheckUnknown(self):
1113        """
1114        Unknown fields are checked, not removed if filterUnknown False.
1115        """
1116        checked = []
1117        fieldDefs = {}
1118        form = data_form.Form('submit')
1119        form.addField(data_form.Field('list-single', var='pubsub#description',
1120                                                     value='a node'))
1121        field = form.fields['pubsub#description']
1122        field.typeCheck = lambda : checked.append(None)
1123        form.typeCheck(fieldDefs, filterUnknown=False)
1124
1125        self.assertIn('pubsub#description', form.fields)
1126        self.assertEqual([None], checked)
1127
1128
1129    def test_typeCheckUnknownNoType(self):
1130        """
1131        Unknown fields without type are not checked.
1132        """
1133        checked = []
1134        fieldDefs = {}
1135        form = data_form.Form('submit')
1136        form.addField(data_form.Field(None, var='pubsub#description',
1137                                            value='a node'))
1138        field = form.fields['pubsub#description']
1139        field.typeCheck = lambda : checked.append(None)
1140        form.typeCheck(fieldDefs, filterUnknown=False)
1141
1142        self.assertIn('pubsub#description', form.fields)
1143        self.assertEqual([], checked)
1144
1145
1146    def test_typeCheckUnknownRemoved(self):
1147        """
1148        Unknown fields are not checked, and removed if filterUnknown True.
1149        """
1150        checked = []
1151        fieldDefs = {}
1152        form = data_form.Form('submit')
1153        form.addField(data_form.Field('list-single', var='pubsub#description',
1154                                                     value='a node'))
1155        field = form.fields['pubsub#description']
1156        field.typeCheck = lambda : checked.append(None)
1157        form.typeCheck(fieldDefs, filterUnknown=True)
1158
1159        self.assertNotIn('pubsub#description', form.fields)
1160        self.assertEqual([], checked)
1161
1162
1163
1164class FindFormTest(unittest.TestCase):
1165    """
1166    Tests for L{data_form.findForm}.
1167    """
1168
1169    def test_findForm(self):
1170        element = domish.Element((None, 'test'))
1171        theForm = data_form.Form('submit', formNamespace='myns')
1172        element.addChild(theForm.toElement())
1173        form = data_form.findForm(element, 'myns')
1174        self.assertEqual('myns', form.formNamespace)
1175
1176
1177    def test_noFormType(self):
1178        element = domish.Element((None, 'test'))
1179        otherForm = data_form.Form('submit')
1180        element.addChild(otherForm.toElement())
1181        form = data_form.findForm(element, 'myns')
1182        self.assertIdentical(None, form)
1183
1184
1185    def test_noFormTypeCancel(self):
1186        """
1187        Cancelled forms don't have a FORM_TYPE field, the first is returned.
1188        """
1189        element = domish.Element((None, 'test'))
1190        cancelledForm = data_form.Form('cancel')
1191        element.addChild(cancelledForm.toElement())
1192        form = data_form.findForm(element, 'myns')
1193        self.assertEqual('cancel', form.formType)
1194
1195
1196    def test_otherFormType(self):
1197        """
1198        Forms with other FORM_TYPEs are ignored.
1199        """
1200        element = domish.Element((None, 'test'))
1201        otherForm = data_form.Form('submit', formNamespace='otherns')
1202        element.addChild(otherForm.toElement())
1203        form = data_form.findForm(element, 'myns')
1204        self.assertIdentical(None, form)
1205
1206
1207    def test_otherFormTypeCancel(self):
1208        """
1209        Cancelled forms with another FORM_TYPE are ignored.
1210        """
1211        element = domish.Element((None, 'test'))
1212        cancelledForm = data_form.Form('cancel', formNamespace='otherns')
1213        element.addChild(cancelledForm.toElement())
1214        form = data_form.findForm(element, 'myns')
1215        self.assertIdentical(None, form)
1216
1217
1218    def test_noElement(self):
1219        """
1220        When None is passed as element, None is returned.
1221        """
1222        element = None
1223        form = data_form.findForm(element, 'myns')
1224        self.assertIdentical(None, form)
1225
1226
1227    def test_noForm(self):
1228        """
1229        When no child element is a form, None is returned.
1230        """
1231        element = domish.Element((None, 'test'))
1232        form = data_form.findForm(element, 'myns')
1233        self.assertIdentical(None, form)
1234    def test_typeCheckNoFieldDefs(self):
1235        """
1236        If there are no field defs, an empty dictionary is assumed.
1237        """
1238        checked = []
1239        form = data_form.Form('submit')
1240        form.addField(data_form.Field('list-single', var='pubsub#description',
1241                                                     value='a node'))
1242        field = form.fields['pubsub#description']
1243        field.typeCheck = lambda : checked.append(None)
1244        form.typeCheck()
1245
1246        self.assertIn('pubsub#description', form.fields)
1247        self.assertEqual([None], checked)
Note: See TracBrowser for help on using the repository browser.