testForm.py 6.58 KB
Newer Older
1
# -*- coding: utf-8 -*-
2
import unittest, re
3
import Zope2
4 5 6 7 8 9 10 11 12 13 14 15

# XXX this does not work for zope2.x if x < 3
# can we fake this? should we do this?
from Testing import makerequest

from Products.Formulator.Form import ZMIForm
from Products.Formulator.Errors import ValidationError, FormValidationError
from Products.Formulator.MethodField import Method
from Products.Formulator.TALESField import TALESMethod

from Products.PythonScripts.PythonScript import PythonScript

16 17 18
import transaction
from Testing import ZopeTestCase
ZopeTestCase.installProduct('Formulator')
19 20 21 22 23 24 25 26

""" random assembly testing some reported bugs.
    This is _not_ a structured or even complete test suite
"""

class FormTestCase(unittest.TestCase):

    def setUp(self):
27 28
        transaction.begin()
        self.connection = Zope2.DB.open()
29 30 31 32 33 34 35 36 37
        self.root = makerequest.makerequest(
            self.connection.root()['Application'])

        self.root.manage_addProduct['Formulator'] \
                 .manage_add('form', 'Test Form')
        self.form = self.root.form


    def tearDown(self):
38
        transaction.abort()
39
        self.connection.close()
40

41 42 43 44 45

    def test_has_field(self):
        """ test if has_field works, if one asks for a non-field attribute.
            this has raised AttributeError "aq_explicit" in previous versions
        """
46
        self.assertFalse(self.form.has_field('title'))
47 48 49 50 51 52 53 54 55

    def _test_list_values(self):
        """ test if a list of values returned by TALES (override) expressions
        is interpreted properly.
        If a TALES tab returns a sequence of items and some item is
        actually a string of length 2 (e.g. "ok"), this previously
        has lead to a item text of 'o' and a display value of 'k'
        (as the this is actually a sequence of length 2 ...)
         See http://sourceforge.net/mailarchive/forum.php?thread_id=1359918&forum_id=1702
56

57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77
        Actually the original problem still does not work,
        as passing a list of int's is not yet supported.
        If it should, please uncomment the second part of the test.
        """

        # XXX deactivated: this maybe should not be fixed at all

        self.form.manage_addField('list_field', 'Test List Field', 'ListField')

        # adding a python script to be called by the override tab
        # FIXME: the following does not work, as the fake-request
        # does not have a "form" atribute (?)
        #self.root.manage_addProduct['PythonScripts'] \
        #         .manage_addPythonScript('override_test', 'Test for override')
        #
        #self.root._getOb('override_test').write("return ['ok', 'no']\n")

        self.form.override_test = PythonScript('override_test')
        self.form.override_test.write("return ['ok', 'no']\n")
        # ps._makeFunction()

78

79 80 81 82 83 84 85 86 87
        list_field = getattr(self.form, 'list_field')
        list_field.values['items'] = [ ('ok', 'ok'), ('no', 'no') ]

        items1 = list_field.render()

        # test TALES
        list_field.tales['items'] = TALESMethod("python:['ok', 'no']")
        items2 = list_field.render()

88
        self.assertEqual(items1, items2)
89 90 91 92 93

        # test override
        del list_field.tales['items']
        list_field.overrides['items'] = Method('override_test')
        items2 = list_field.render()
94

95
        self.assertEqual(items1, items2)
96

97 98 99 100 101 102 103 104
        # test if TALES returns a list of e.g. int
        #list_field.values['items'] = [ ('42', '42'), ('88', '88') ]
        #
        #items1 = list_field.render()
        #
        #list_field.tales['items'] = TALESMethod("python:[42, 88]")
        #items2 = list_field.render()
        #
105
        #self.assertEqual(items1, items2)
106 107 108 109 110 111 112 113 114 115 116 117

    def test_labels(self):
        self.form.manage_addField(
            'label_field', 'Test Label Field', 'LabelField')

        self.form.label_field.overrides['default'] = "Some label"

        self.form.manage_addField(
            'int_field', 'Test integer field', 'IntegerField')

        result = self.form.validate_all(
            {'field_int_field': '3'})
118
        self.assertEqual({'int_field': 3}, result)
119 120


121 122 123 124 125 126 127 128 129 130 131 132 133 134
    def test_datetime_timezone_rendering(self):
        self.form.manage_addProduct['Formulator']\
                 .manage_addField('date_time','Test Field','DateTimeField')
        field = self.form.date_time
        sub_form = field.sub_form
        if sub_form.has_field('timezone'):
          del sub_form.fields['timezone']
        #now timezone is not presented
        self.assertFalse(self.form.date_time.sub_form.has_field('timezone'))
        field._edit({'timezone_style': 1})
        #test if timezone's presented
        self.assertTrue(self.form.date_time.sub_form.has_field('timezone'))


135 136 137 138 139 140
    def test_datetime_css_class_rendering(self):
        # test that a bug is fixed, which causing the css_class value
        # not to be rendered
        self.form.manage_addProduct['Formulator']\
                 .manage_addField('date_time','Test Field','DateTimeField')
        field = self.form.date_time
141

142 143 144
        css_matcher = re.compile('class="([^"]*)"')

        # initially no css class is set
145
        self.assertEqual(0, len(css_matcher.findall(field.render())))
146

147
        # edit the field, bypassing validation ...
148 149 150 151
        field._edit({'css_class':'some_class'})

        # now we should have five matches for the five subfields ...
        css_matches = css_matcher.findall(field.render())
152
        self.assertEqual(5, len(css_matches))
153 154
        # ... and all have the given value:
        for m in css_matches:
155
            self.assertEqual('some_class',m)
156 157 158 159 160 161

        # change the input style: the css needs to be
        # propagated to the newly created subfields
        current_style = field['input_style']
        other_style = {'list':'text', 'text':'list'} [current_style]
        field._edit({'input_style':other_style})
162

163 164
        # still the css classes should remain the same
        css_matches = css_matcher.findall(field.render())
165
        self.assertEqual(5, len(css_matches))
166
        for m in css_matches:
167
            self.assertEqual('some_class',m)
168 169 170 171

        # now just change to another value:
        field._edit({'css_class':'other_class'})
        css_matches = css_matcher.findall(field.render())
172
        self.assertEqual(5, len(css_matches))
173
        for m in css_matches:
174
            self.assertEqual('other_class',m)
175 176 177 178

        # and clear the css_class field:
        field._edit({'css_class':''})
        css_matches = css_matcher.findall(field.render())
179
        self.assertEqual(0, len(css_matches))
180 181 182 183 184 185 186 187 188 189 190 191 192


def test_suite():
    suite = unittest.TestSuite()

    suite.addTest(unittest.makeSuite(FormTestCase, 'test'))
    return suite

def main():
    unittest.TextTestRunner().run(test_suite())

if __name__ == '__main__':
    main()