Back to index

plone3  3.1.7
test_fields.py
Go to the documentation of this file.
00001 ################################################################################
00002 #
00003 # Copyright (c) 2002-2005, Benjamin Saller <bcsaller@ideasuite.com>, and
00004 #                              the respective authors. All rights reserved.
00005 # For a list of Archetypes contributors see docs/CREDITS.txt.
00006 #
00007 # Redistribution and use in source and binary forms, with or without
00008 # modification, are permitted provided that the following conditions are met:
00009 #
00010 # * Redistributions of source code must retain the above copyright notice, this
00011 #   list of conditions and the following disclaimer.
00012 # * Redistributions in binary form must reproduce the above copyright notice,
00013 #   this list of conditions and the following disclaimer in the documentation
00014 #   and/or other materials provided with the distribution.
00015 # * Neither the name of the author nor the names of its contributors may be used
00016 #   to endorse or promote products derived from this software without specific
00017 #   prior written permission.
00018 #
00019 # THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
00020 # WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
00021 # WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
00022 # FOR A PARTICULAR PURPOSE.
00023 #
00024 ################################################################################
00025 """
00026 """
00027 
00028 import os
00029 
00030 from zope.interface import implements
00031 from zope.component import getSiteManager
00032 from zope.schema.interfaces import IVocabularyFactory
00033 from zope.schema.vocabulary import SimpleVocabulary
00034 
00035 from Products.Archetypes.tests.atsitetestcase import ATSiteTestCase
00036 from Products.Archetypes.tests.atsitetestcase import portal_name
00037 from Products.Archetypes.tests.utils import mkDummyInContext
00038 from Products.Archetypes.tests.utils import PACKAGE_HOME
00039 
00040 from Products.Archetypes.atapi import *
00041 from Products.Archetypes.interfaces import IFieldDefaultProvider
00042 from Products.Archetypes.interfaces.vocabulary import IVocabulary
00043 from Products.Archetypes import Field as at_field
00044 from Products.Archetypes.Field import ScalableImage
00045 from Products.Archetypes import config
00046 from Products import PortalTransforms
00047 from OFS.Image import File, Image
00048 from DateTime import DateTime
00049 
00050 
00051 test_fields = [
00052           ('ObjectField', 'objectfield'),
00053           ('StringField', 'stringfield'),
00054           ('FileField', 'filefield'),
00055           ('TextField', 'textfield'),
00056           ('DateTimeField', 'datetimefield'),
00057           ('LinesField','linesfield'),
00058           ('IntegerField', 'integerfield'),
00059           ('FloatField', 'floatfield'),
00060           ('FixedPointField', 'fixedpointfield1'),
00061           ('FixedPointField', 'fixedpointfield2'),
00062           ('BooleanField', 'booleanfield'),
00063           ('ImageField', 'imagefield'),
00064           ('PhotoField', 'photofield'),
00065           # 'ReferenceField', 'ComputedField', 'CMFObjectField',
00066           ]
00067 
00068 field_instances = []
00069 for type, name in test_fields:
00070     field_instances.append(getattr(at_field, type)(name))
00071 
00072 txt_file = open(os.path.join(PACKAGE_HOME, 'input', 'rest1.rst'))
00073 txt_content = txt_file.read()
00074 img_file = open(os.path.join(PACKAGE_HOME, 'input', 'tool.gif'), 'rb')
00075 img_content = img_file.read()
00076 
00077 field_values = {'objectfield':'objectfield',
00078                 'stringfield':'stringfield',
00079                 'filefield_file':txt_file,
00080                 'textfield':'textfield',
00081                 'datetimefield':'',
00082                 'datetimefield_year':'2003',
00083                 'datetimefield_month':'01',
00084                 'datetimefield_day':'01',
00085                 'datetimefield_hour':'03',
00086                 'datetimefield_minute':'04',
00087                 'linesfield':'bla\nbla',
00088                 'integerfield':'1',
00089                 'floatfield':'1.5',
00090                 'fixedpointfield1': '1.5',
00091                 'fixedpointfield2': '1,5',
00092                 'booleanfield':'1',
00093                 'imagefield_file':img_file,
00094                 'photofield_file':img_file}
00095 
00096 expected_values = {'objectfield':'objectfield',
00097                    'stringfield':'stringfield',
00098                    'filefield':txt_content,
00099                    'textfield':'textfield',
00100                    'datetimefield':DateTime('2003-01-01 03:04'),
00101                    'linesfield':('bla', 'bla'),
00102                    'integerfield': 1,
00103                    'floatfield': 1.5,
00104                    'fixedpointfield1':  '1.50',
00105                    'fixedpointfield2': '1.50',
00106                    'booleanfield': 1,
00107                    'imagefield':'<img src="%s/dummy/imagefield" alt="Spam" title="Spam" height="16" width="16" />' % portal_name, 
00108                    'photofield':'<img src="%s/dummy/photofield/variant/original" alt="" title="" height="16" width="16" border="0" />' % portal_name
00109                    }
00110 
00111 empty_values = {'objectfield':None,
00112                    'stringfield':'',
00113                    'filefield':None,
00114                    'textfield':'',
00115                    'datetimefield':'2007-00-00',
00116                    'linesfield':(),
00117                    'integerfield': None,
00118                    'floatfield': None,
00119                    'fixedpointfield1': None,
00120                    'fixedpointfield2': None,
00121                    'booleanfield': None,
00122                }
00123 
00124 schema = Schema(tuple(field_instances))
00125 sampleDisplayList = DisplayList([('e1', 'e1'), ('element2', 'element2')])
00126 
00127 class sampleInterfaceVocabulary:
00128     __implements__ = IVocabulary
00129     def getDisplayList(self, instance):
00130         return sampleDisplayList
00131 
00132 class Dummy(BaseContentMixin):
00133     def Title(self):
00134         # required for ImageField
00135         return 'Spam'
00136 
00137     def aMethod(self):
00138         return sampleDisplayList
00139 
00140     def default_val(self):
00141         return "World"
00142 
00143 class DummyVocabulary(object):
00144     implements(IVocabularyFactory)
00145 
00146     def __call__(self, context):
00147         return SimpleVocabulary.fromItems([("title1", "value1"), ("t2", "v2")])
00148 
00149 DummyVocabFactory = DummyVocabulary()
00150 
00151 class FakeRequest:
00152 
00153     def __init__(self):
00154         self.other = {}
00155         self.form = {}
00156 
00157 
00158 class ProcessingTest(ATSiteTestCase):
00159 
00160     def afterSetUp(self):
00161         self.setRoles(['Manager'])
00162         ATSiteTestCase.afterSetUp(self)
00163         self._dummy = mkDummyInContext(Dummy, oid='dummy', context=self.portal,
00164                                        schema=schema)
00165         txt_file.seek(0)
00166         img_file.seek(0)
00167 
00168     def makeDummy(self):
00169         return self._dummy
00170 
00171     def test_processing(self):
00172         dummy = self.makeDummy()
00173         request = FakeRequest()
00174         request.form.update(field_values)
00175         dummy.REQUEST = request
00176         dummy.processForm(data=1)
00177         for k, v in expected_values.items():
00178             got = dummy.getField(k).get(dummy)
00179             if isinstance(got, File):
00180                 got = str(got)
00181             self.assertEquals(got, v, 'got: %r, expected: %r, field "%s"' %
00182                               (got, v, k))
00183 
00184     def test_processing_fieldset(self):
00185         dummy = self.makeDummy()
00186         request = FakeRequest()
00187         request.form.update(field_values)
00188         request.form['fieldset'] = 'default'
00189         dummy.REQUEST = request
00190         dummy.processForm()
00191         for k, v in expected_values.items():
00192             got = dummy.getField(k).get(dummy)
00193             if isinstance(got, (File, ScalableImage, Image)):
00194                 got = str(got)
00195             self.assertEquals(got, v, 'got: %r, expected: %r, field "%s"' %
00196                               (got, v, k))
00197 
00198     def test_get_size(self):
00199         dummy = self.makeDummy()
00200         request = FakeRequest()
00201         request.form.update(field_values)
00202         request.form['fieldset'] = 'default'
00203         dummy.REQUEST = request
00204         dummy.processForm()
00205         size = 0
00206         for k, v in expected_values.items():
00207             field = dummy.getField(k)
00208             s = field.get_size(dummy)
00209             size+=s
00210             self.failUnless(s, 'got: %s, field: %s' % (s, k))
00211         self.failUnlessEqual(size, dummy.get_size())
00212 
00213     def test_validation(self):
00214         dummy = self.makeDummy()
00215         request = FakeRequest()
00216         request.form.update(field_values)
00217         request.form['fieldset'] = 'default'
00218         dummy.REQUEST = request
00219         errors = {}
00220         dummy.validate(errors=errors)
00221         self.failIf(errors, errors)
00222 
00223     def test_required(self):
00224         request = FakeRequest()
00225         request.form.update(empty_values)
00226         request.form['fieldset'] = 'default'
00227         self._test_required(request)
00228         
00229     def test_required_empty_request(self):
00230         request = FakeRequest()
00231         request.form = {}
00232         request.form['fieldset'] = 'default'
00233         self._test_required(request)
00234 
00235     def _test_required(self, request):
00236         dummy = self.makeDummy()
00237         f_names = []
00238 
00239         schema = dummy.Schema()
00240         for f in schema.fields():
00241             name = f.getName()
00242             f.required = 1
00243             f_names.append(name)
00244         errors = {}
00245         dummy.validate(REQUEST=request, errors=errors)
00246         self.failUnless(errors, "Errors dictionary is empty.")
00247         err_fields = errors.keys()
00248         failures = []
00249         for f_name in f_names:
00250             if f_name not in err_fields:
00251                 failures.append(f_name)
00252         self.failIf(failures, "%s failed to report error." % failures)
00253 
00254     def test_static_vocabulary(self):
00255         dummy = self.makeDummy()
00256         request = FakeRequest()
00257         field = dummy.Schema().fields()[0]
00258 
00259         # Default
00260         self.failUnlessEqual(field.Vocabulary(), DisplayList())
00261         # DisplayList
00262         field.vocabulary = sampleDisplayList()
00263         self.failUnlessEqual(field.Vocabulary(), sampleDisplayList)
00264         # List
00265         field.vocabulary = ['e1', 'element2']
00266         self.failUnlessEqual(field.Vocabulary(), sampleDisplayList)
00267         # 2-Tuples
00268         field.vocabulary = [('e1', 'e1'), ('element2', 'element2')]
00269         self.failUnlessEqual(field.Vocabulary(), sampleDisplayList)
00270 
00271     def test_dynamic_vocabulary(self):
00272         dummy = self.makeDummy()
00273         request = FakeRequest()
00274         field = dummy.Schema().fields()[0]
00275 
00276         # Default
00277         self.failUnlessEqual(field.Vocabulary(dummy), DisplayList())
00278         # Method
00279         field.vocabulary = 'aMethod'
00280         self.failUnlessEqual(field.Vocabulary(dummy), sampleDisplayList)
00281         # DisplayList
00282         field.vocabulary = sampleDisplayList()
00283         self.failUnlessEqual(field.Vocabulary(dummy), sampleDisplayList)
00284         # List
00285         field.vocabulary = ['e1', 'element2']
00286         self.failUnlessEqual(field.Vocabulary(dummy), sampleDisplayList)
00287         # 2-Tuples
00288         field.vocabulary = [('e1', 'e1'), ('element2', 'element2')]
00289         self.failUnlessEqual(field.Vocabulary(dummy), sampleDisplayList)
00290         # Interface
00291         field.vocabulary = sampleInterfaceVocabulary()
00292         self.failUnlessEqual(field.Vocabulary(dummy), sampleDisplayList)
00293 
00294     def test_factory_vocabulary(self):
00295         dummy = self.makeDummy()
00296         request = FakeRequest()
00297         field = dummy.Schema().fields()[0]
00298 
00299         # Default
00300         self.failUnlessEqual(field.Vocabulary(dummy), DisplayList())
00301         
00302         expected = DisplayList([('value1', 'title1'), ('v2', 't2')])
00303         
00304         # # Vocabulary factory
00305         field.vocabulary = ()
00306         field.vocabulary_factory = 'archetypes.tests.dummyvocab'
00307         getSiteManager().registerUtility(component=DummyVocabFactory, name='archetypes.tests.dummyvocab')
00308         self.failUnlessEqual(field.Vocabulary(dummy), expected)
00309         getSiteManager().unregisterUtility(component=DummyVocabFactory, name='archetypes.tests.dummyvocab')
00310 
00311     def test_defaults(self):
00312         dummy = self.makeDummy()
00313         request = FakeRequest()
00314         field = dummy.Schema().fields()[0]
00315 
00316         # Default
00317         self.failUnlessEqual(field.getDefault(dummy), None)
00318         
00319         # Value
00320         field.default = "Hello"
00321         self.failUnlessEqual(field.getDefault(dummy), 'Hello')
00322         
00323         # Method
00324         field.default = None
00325         field.default_method = 'default_val'
00326         self.failUnlessEqual(field.getDefault(dummy), 'World')
00327 
00328         # Adapter
00329         field.default_method = None
00330         
00331         class DefaultFor(object):
00332             implements(IFieldDefaultProvider)
00333             def __init__(self, context):
00334                 self.context = context
00335             def __call__(self):
00336                 return "Adapted"
00337         
00338         getSiteManager().registerAdapter(factory=DefaultFor, required=(Dummy,), name=field.__name__)
00339         self.failUnlessEqual(field.getDefault(dummy), 'Adapted')
00340         getSiteManager().unregisterAdapter(factory=DefaultFor, required=(Dummy,), name=field.__name__)
00341 
00342 
00343 class DownloadTest(ATSiteTestCase):
00344 
00345     def afterSetUp(self):
00346         # Set up a content object with a field that has a word
00347         # document in it
00348         ATSiteTestCase.afterSetUp(self)
00349         self.dummy = mkDummyInContext(
00350             Dummy, oid='dummy', context=self.portal, schema=schema)
00351         self.field = self.dummy.getField('textfield')
00352         ptpath = PortalTransforms.__path__[0]
00353         self.wordfile = open('%s/tests/input/test.doc' % ptpath)
00354         self.field.getMutator(self.dummy)(self.wordfile.read())
00355         self.request = self.app.REQUEST
00356         self.response = self.request.response
00357     
00358     def test_download_from_textfield(self):
00359         # make sure field data doesn't get transformed when using the
00360         # download method
00361         value = self.field.download(self.dummy, no_output=True)
00362         self.failIf(isinstance(value, str))
00363 
00364     def test_download_filename_encoding(self):
00365         # When downloading, the filename is converted to ASCII:
00366         self.field.setFilename(self.dummy, '\xc3\xbcberzeugen')
00367         self.field.download(self.dummy, no_output=True)
00368         self.assertEqual(self.response.headers['content-disposition'],
00369                          'attachment; filename="uberzeugen"')
00370         
00371 def test_suite():
00372     from unittest import TestSuite, makeSuite
00373     suite = TestSuite()
00374     suite.addTest(makeSuite(ProcessingTest))
00375     suite.addTest(makeSuite(DownloadTest))
00376     return suite