source: wokkel/test/test_data_form.py @ 84:3fe44cf07366

Last change on this file since 84:3fe44cf07366 was 80:3ee3e922549d, checked in by Ralph Meijer <ralphm@…>, 12 years ago

Move findForm to wokkel.data_form

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