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

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

Replace the term 'WAeUP' by SIRP which is a WAeUP product.

  • Property svn:keywords set to Id
File size: 11.5 KB
Line 
1## $Id: test_converters.py 7321 2011-12-10 06:15:17Z 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        #import pdb; pdb.set_trace()
258        #assert data['birthday'] == datetime.date(1945, 12, 23)
259        assert err[0][1] =='Invalid datetime data'
260
261        # '08' is not interpreted as octal number
262        err, inv_err, data = converter.fromStringDict(
263            dict(birthday='1945-12-08'), contact)
264        assert data['birthday'] == datetime.date(1945, 12, 8)
265        return
266
267    def test_date_invalid(self):
268        contact = Contact()
269        converter = IObjectConverter(IContact) # a converter to IContact
270        err, inv_err, data = converter.fromStringDict(
271            dict(birthday='not-a-date'), contact)
272        self.assertEqual(err, [('birthday', u'Invalid datetime data')])
273
274    def test_inject_formfields_select(self):
275        # We can use our own formfields and select only a subset of fields
276        contact = Contact()
277        converter = IObjectConverter(IContact) # a converter to IContact
278        input_data = dict(name='Bruno', age='99', vip='on')
279        err, inv_err, data = converter.fromStringDict(
280            input_data, contact, form_fields=form_fields_select)
281        self.assertEqual(data['name'], 'Bruno')
282        assert 'age' not in data.keys()
283        assert data['vip'] is True
284        return
285
286    def test_inject_formfields_omit(self):
287        # We can use our own formfields and omit some fields
288        contact = Contact()
289        converter = IObjectConverter(IContact) # a converter to IContact
290        input_data = dict(name='Bruno', age='99', vip='on')
291        err, inv_err, data = converter.fromStringDict(
292            input_data, contact, form_fields=form_fields_omit)
293        self.assertEqual(data['age'], 99)
294        assert 'name' not in data.keys()
295        assert 'vip' not in data.keys()
296        return
297
298    def test_factory(self):
299        # We can use factories to convert values
300        converter = IObjectConverter(IContact) # a converter to IContact
301        # pass string ``contact`` instead of a real object
302        err, inv_err, data = converter.fromStringDict(
303            dict(name='Gabi', age='23'), 'contact')
304        self.assertEqual(data['age'], 23)
305        self.assertEqual(data['name'], u'Gabi')
306        return
307
308    def test_choice_vocab(self):
309        # We can handle vocabularies
310        converter = IObjectConverter(IContact) # a converter to IContact
311        err, inv_err, data = converter.fromStringDict(
312            dict(fav_color='blue'), 'contact')
313        assert data['fav_color'] == u'blue'
314        assert isinstance(data['fav_color'], unicode)
315        return
316
317    def test_choice_vocab_invalid_value(self):
318        # We can handle vocabularies
319        converter = IObjectConverter(IContact) # a converter to IContact
320        err, inv_err, data = converter.fromStringDict(
321            dict(fav_color='magenta'), 'contact')
322        self.assertEqual(err, [('fav_color', u'Invalid value')])
323        assert 'fav_color' not in data.keys()
324        return
325
326    def test_non_string_choice(self):
327        # We can handle vocabs with non-string values
328        converter = IObjectConverter(IContact) # a converter to IContact
329        err, inv_err, data = converter.fromStringDict(
330            dict(num_cars='1'), 'contact')
331        assert data['num_cars'] == 1
332        return
Note: See TracBrowser for help on using the repository browser.