source: main/waeup.sirp/trunk/src/waeup/sirp/utils/tests/test_converters.py @ 9676

Last change on this file since 9676 was 7649, checked in by Henrik Bettermann, 13 years ago

Remove uncommented pdb break points.

  • Property svn:keywords set to Id
File size: 11.5 KB
Line 
1## $Id: test_converters.py 7649 2012-02-14 15:00:47Z henrik $
2##
3## Copyright (C) 2011 Uli Fouquet & Henrik Bettermann
4## This program is free software; you can redistribute it and/or modify
5## it under the terms of the GNU General Public License as published by
6## the Free Software Foundation; either version 2 of the License, or
7## (at your option) any later version.
8##
9## This program is distributed in the hope that it will be useful,
10## but WITHOUT ANY WARRANTY; without even the implied warranty of
11## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12## GNU General Public License for more details.
13##
14## You should have received a copy of the GNU General Public License
15## along with this program; if not, write to the Free Software
16## Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
17##
18"""
19Tests for converterts.
20"""
21import datetime
22import shutil
23import tempfile
24from zope import schema
25from zope.component import provideUtility
26from zope.component.factory import Factory
27from zope.component.hooks import clearSite
28from zope.component.interfaces import IFactory
29from zope.formlib import form
30from zope.interface import (
31    Interface, implements, invariant, Invalid, implementedBy)
32
33from waeup.sirp.app import University
34from waeup.sirp.testing import FunctionalLayer, FunctionalTestCase
35from waeup.sirp.university import Faculty
36from waeup.sirp.utils.converters import IObjectConverter
37from waeup.sirp.utils.helpers import attrs_to_fields
38from waeup.sirp.interfaces import SimpleSIRPVocabulary
39
40colors = SimpleSIRPVocabulary(
41    ('Red', u'red'),
42    ('Green', u'green'),
43    ('Blue', u'blue'),
44    )
45car_nums = SimpleSIRPVocabulary(
46    ('None', 0),
47    ('One', 1),
48    ('Two', 2),
49    ('Three', 3),
50    )
51class IContact(Interface):
52    """Sample interface for sample content type used here in tests.
53    """
54    name = schema.TextLine(
55        title = u'Name',
56        default = u'Manfred',
57        readonly = True,
58        )
59    age = schema.Int(
60        title = u'Age',
61        default = 23,
62        required = True,
63        )
64    city = schema.TextLine(
65        title = u'City',
66        required = True,
67        )
68    vip = schema.Bool(
69        title = u'Celebrity',
70        default = False,
71        required = True,
72        )
73    birthday = schema.Date(
74        title = u'Birthday',
75        default = None,
76        )
77    fav_color = schema.Choice(
78        title = u'Favourite color',
79        default = u'red',
80        vocabulary = colors,
81        )
82    num_cars = schema.Choice(
83        title = u'Number of cars owned',
84        default = None,
85        vocabulary = car_nums,
86        )
87    @invariant
88    def kevinIsYoung(contact):
89        if contact.age > 16 and contact.name == 'Kevin':
90            raise Invalid('Kevins are age 16 or below.')
91
92class Contact(object):
93    """Sample content type.
94    """
95    implements(IContact)
96Contact = attrs_to_fields(Contact)
97
98form_fields_select = form.Fields(IContact).select('name', 'vip')
99form_fields_omit = form.Fields(IContact).omit('name', 'vip')
100
101class ContactFactory(object):
102    """A factory for faculty containers.
103    """
104    implements(IContact)
105
106    def __call__(self, *args, **kw):
107        return Faculty()
108
109    def getInterfaces(self):
110        return implementedBy(Faculty)
111
112class ConverterTests(FunctionalTestCase):
113
114    layer = FunctionalLayer
115
116    def setUp(self):
117        super(ConverterTests, self).setUp()
118
119        # Setup a sample site for each test
120        app = University()
121        self.dc_root = tempfile.mkdtemp()
122        app['datacenter'].setStoragePath(self.dc_root)
123
124        # Prepopulate the ZODB...
125        self.getRootFolder()['app'] = app
126        self.app = self.getRootFolder()['app']
127
128        self.workdir = tempfile.mkdtemp()
129
130        # Create a factory for contacts and register it as global utility
131        factory = Factory(Contact)
132        provideUtility(factory, IFactory, 'contact')
133        return
134
135    def tearDown(self):
136        super(ConverterTests, self).tearDown()
137        shutil.rmtree(self.workdir)
138        shutil.rmtree(self.dc_root)
139        clearSite()
140        return
141
142    def test_valid_data(self):
143        contact = Contact()
144        contact.age = 33
145        input_data = dict(name='Rudi', age='99')
146        converter = IObjectConverter(IContact) # a converter to IContact
147        err, inv_err, data = converter.fromStringDict(
148            input_data, contact)
149        assert data['name'] == 'Rudi'
150        assert data['age'] == 99
151        return
152
153    def test_bool(self):
154        contact1 = Contact()
155        contact2 = Contact()
156        input_data1 = dict(vip='on')
157        input_data2 = dict(vip='')
158        converter = IObjectConverter(IContact) # a converter to IContact
159        err1, inv_err1, data1 = converter.fromStringDict(
160            input_data1, contact1)
161        err2, inv_err2, data2 = converter.fromStringDict(
162            input_data2, contact2)
163        assert data1['vip'] is True
164        assert data2['vip'] is False
165
166    def test_bool_nonstandard_values1(self):
167        # We accept 'true', 'True', 'tRuE', 'faLSE' and similar.
168        contact1 = Contact()
169        contact2 = Contact()
170        input_data1 = dict(vip='True')
171        input_data2 = dict(vip='false')
172        converter = IObjectConverter(IContact) # a converter to IContact
173        err1, inv_err1, data1 = converter.fromStringDict(
174            input_data1, contact1)
175        err2, inv_err2, data2 = converter.fromStringDict(
176            input_data2, contact2)
177        assert data1['vip'] is True
178        assert data2['vip'] is False
179
180    def test_bool_nonstandard_values2(self):
181        # We accept '1' and '0' as bool values.
182        contact1 = Contact()
183        contact2 = Contact()
184        input_data1 = dict(vip='1')
185        input_data2 = dict(vip='0')
186        converter = IObjectConverter(IContact) # a converter to IContact
187        err1, inv_err1, data1 = converter.fromStringDict(
188            input_data1, contact1)
189        err2, inv_err2, data2 = converter.fromStringDict(
190            input_data2, contact2)
191        assert data1['vip'] is True
192        assert data2['vip'] is False
193
194    def test_bool_nonstandard_values3(self):
195        # We accept 'yEs', 'no' and similar as bool values.
196        contact1 = Contact()
197        contact2 = Contact()
198        input_data1 = dict(vip='Yes')
199        input_data2 = dict(vip='no')
200        converter = IObjectConverter(IContact) # a converter to IContact
201        err1, inv_err1, data1 = converter.fromStringDict(
202            input_data1, contact1)
203        err2, inv_err2, data2 = converter.fromStringDict(
204            input_data2, contact2)
205        assert data1['vip'] is True
206        assert data2['vip'] is False
207
208    def test_int(self):
209        contact = Contact()
210        input_data = dict(age='99')
211        converter = IObjectConverter(IContact) # a converter to IContact
212        err, inv_err, data = converter.fromStringDict(
213            input_data, contact)
214        assert data['age'] == 99
215        return
216
217    def test_int_invalid(self):
218        contact = Contact()
219        input_data = dict(age='sweet sixteen')
220        converter = IObjectConverter(IContact) # a converter to IContact
221        err, inv_err, new_contact = converter.fromStringDict(
222            input_data, contact)
223        self.assertEqual(err, [('age', u'Invalid integer data')])
224        return
225
226    def test_textline(self):
227        contact = Contact()
228        input_data = dict(name='Rudi')
229        converter = IObjectConverter(IContact) # a converter to IContact
230        err, inv_err, data = converter.fromStringDict(
231            input_data, contact)
232        self.assertEqual(data['name'], u'Rudi')
233        assert isinstance(data['name'], unicode)
234        return
235
236    def test_invariant(self):
237        contact = Contact()
238        input_data = dict(name='Kevin', age='22')
239        converter = IObjectConverter(IContact) # a converter to IContact
240        err, inv_err, new_contact = converter.fromStringDict(
241            input_data, contact)
242        self.assertEqual(inv_err, ['Kevins are age 16 or below.'])
243        return
244
245    def test_date(self):
246        contact = Contact()
247        converter = IObjectConverter(IContact) # a converter to IContact
248
249        # The input format for dates: YYYY-MM-DD
250        err, inv_err, data = converter.fromStringDict(
251            dict(birthday='1945-12-23'), contact)
252        assert data['birthday'] == datetime.date(1945, 12, 23)
253        assert isinstance(data['birthday'], datetime.date)
254
255        err, inv_err, data = converter.fromStringDict(
256            dict(birthday='1945-23-12'), contact)
257        #assert data['birthday'] == datetime.date(1945, 12, 23)
258        assert err[0][1] =='Invalid datetime data'
259
260        # '08' is not interpreted as octal number
261        err, inv_err, data = converter.fromStringDict(
262            dict(birthday='1945-12-08'), contact)
263        assert data['birthday'] == datetime.date(1945, 12, 8)
264        return
265
266    def test_date_invalid(self):
267        contact = Contact()
268        converter = IObjectConverter(IContact) # a converter to IContact
269        err, inv_err, data = converter.fromStringDict(
270            dict(birthday='not-a-date'), contact)
271        self.assertEqual(err, [('birthday', u'Invalid datetime data')])
272
273    def test_inject_formfields_select(self):
274        # We can use our own formfields and select only a subset of fields
275        contact = Contact()
276        converter = IObjectConverter(IContact) # a converter to IContact
277        input_data = dict(name='Bruno', age='99', vip='on')
278        err, inv_err, data = converter.fromStringDict(
279            input_data, contact, form_fields=form_fields_select)
280        self.assertEqual(data['name'], 'Bruno')
281        assert 'age' not in data.keys()
282        assert data['vip'] is True
283        return
284
285    def test_inject_formfields_omit(self):
286        # We can use our own formfields and omit some fields
287        contact = Contact()
288        converter = IObjectConverter(IContact) # a converter to IContact
289        input_data = dict(name='Bruno', age='99', vip='on')
290        err, inv_err, data = converter.fromStringDict(
291            input_data, contact, form_fields=form_fields_omit)
292        self.assertEqual(data['age'], 99)
293        assert 'name' not in data.keys()
294        assert 'vip' not in data.keys()
295        return
296
297    def test_factory(self):
298        # We can use factories to convert values
299        converter = IObjectConverter(IContact) # a converter to IContact
300        # pass string ``contact`` instead of a real object
301        err, inv_err, data = converter.fromStringDict(
302            dict(name='Gabi', age='23'), 'contact')
303        self.assertEqual(data['age'], 23)
304        self.assertEqual(data['name'], u'Gabi')
305        return
306
307    def test_choice_vocab(self):
308        # We can handle vocabularies
309        converter = IObjectConverter(IContact) # a converter to IContact
310        err, inv_err, data = converter.fromStringDict(
311            dict(fav_color='blue'), 'contact')
312        assert data['fav_color'] == u'blue'
313        assert isinstance(data['fav_color'], unicode)
314        return
315
316    def test_choice_vocab_invalid_value(self):
317        # We can handle vocabularies
318        converter = IObjectConverter(IContact) # a converter to IContact
319        err, inv_err, data = converter.fromStringDict(
320            dict(fav_color='magenta'), 'contact')
321        self.assertEqual(err, [('fav_color', u'Invalid value')])
322        assert 'fav_color' not in data.keys()
323        return
324
325    def test_non_string_choice(self):
326        # We can handle vocabs with non-string values
327        converter = IObjectConverter(IContact) # a converter to IContact
328        err, inv_err, data = converter.fromStringDict(
329            dict(num_cars='1'), 'contact')
330        assert data['num_cars'] == 1
331        return
Note: See TracBrowser for help on using the repository browser.