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

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

Set value Id for property svn:keywords in all Python files.

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