Back to index

plone3  3.1.7
test_atfile.py
Go to the documentation of this file.
00001 # -*- coding: utf-8 -*-
00002 #  ATContentTypes http://plone.org/products/atcontenttypes/
00003 #  Archetypes reimplementation of the CMF core types
00004 #  Copyright (c) 2003-2006 AT Content Types development team
00005 #
00006 #  This program is free software; you can redistribute it and/or modify
00007 #  it under the terms of the GNU General Public License as published by
00008 #  the Free Software Foundation; either version 2 of the License, or
00009 #  (at your option) any later version.
00010 #
00011 #  This program is distributed in the hope that it will be useful,
00012 #  but WITHOUT ANY WARRANTY; without even the implied warranty of
00013 #  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00014 #  GNU General Public License for more details.
00015 #
00016 #  You should have received a copy of the GNU General Public License
00017 #  along with this program; if not, write to the Free Software
00018 #  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
00019 #
00020 """
00021 """
00022 
00023 __author__ = 'Christian Heimes <tiran@cheimes.de>'
00024 __docformat__ = 'restructuredtext'
00025 
00026 import unittest
00027 from Testing import ZopeTestCase # side effect import. leave it here.
00028 from Products.ATContentTypes.tests import atcttestcase, atctftestcase
00029 
00030 import time, transaction
00031 from Products.CMFCore.permissions import View
00032 from Products.CMFCore.permissions import ModifyPortalContent
00033 from Products.Archetypes.interfaces.layer import ILayerContainer
00034 from Products.Archetypes.atapi import *
00035 from Products.ATContentTypes.tests.utils import dcEdit
00036 import StringIO
00037 
00038 from Products.ATContentTypes.content.file import ATFile
00039 from Products.ATContentTypes.interfaces import IATFile
00040 from Products.ATContentTypes.interfaces import IFileContent
00041 from Interface.Verify import verifyObject
00042 
00043 # z3 imports
00044 from Products.ATContentTypes.interface import IATFile as Z3IATFile
00045 from Products.ATContentTypes.interface import IFileContent as Z3IFileContent
00046 from zope.interface.verify import verifyObject as Z3verifyObject
00047 
00048 
00049 file_text = """
00050 foooooo
00051 """
00052 
00053 def editATCT(obj):
00054     dcEdit(obj)
00055     obj.edit(file=file_text)
00056 
00057 tests = []
00058 
00059 class TestSiteATFile(atcttestcase.ATCTTypeTestCase):
00060 
00061     klass = ATFile
00062     portal_type = 'File'
00063     title = 'File'
00064     meta_type = 'ATFile'
00065     icon = 'file_icon.gif'
00066 
00067     def test_implementsFileContent(self):
00068         iface = IFileContent
00069         self.failUnless(iface.isImplementedBy(self._ATCT))
00070         self.failUnless(verifyObject(iface, self._ATCT))
00071 
00072     def test_implementsZ3FileContent(self):
00073         iface = Z3IFileContent
00074         self.failUnless(Z3verifyObject(iface, self._ATCT))
00075 
00076     def test_implementsATFile(self):
00077         iface = IATFile
00078         self.failUnless(iface.isImplementedBy(self._ATCT))
00079         self.failUnless(verifyObject(iface, self._ATCT))
00080 
00081     def test_implementsZ3ATFile(self):
00082         iface = Z3IATFile
00083         self.failUnless(Z3verifyObject(iface, self._ATCT))
00084 
00085     def test_edit(self):
00086         new = self._ATCT
00087         editATCT(new)
00088 
00089     def testCompatibilityFileAccess(self):
00090         new = self._ATCT
00091         editATCT(new)
00092         # test for crappy access ways of CMF :)
00093         self.failUnlessEqual(str(new), file_text)
00094         self.failUnlessEqual(new.data, file_text)
00095         self.failUnlessEqual(str(new.getFile()), file_text)
00096         self.failUnlessEqual(new.getFile().data, file_text)
00097         self.failUnlessEqual(new.get_data(), file_text)
00098 
00099     def testCompatibilityContentTypeAccess(self):
00100         new = self._ATCT
00101         editATCT(new)
00102         # TODO: more tests
00103 
00104     def test_schema_marshall(self):
00105         atct = self._ATCT
00106         schema = atct.Schema()
00107         marshall = schema.getLayerImpl('marshall')
00108         marshallers = [PrimaryFieldMarshaller]
00109         try:
00110             from Products.Marshall import ControlledMarshaller
00111             marshallers.append(ControlledMarshaller)
00112         except ImportError:
00113             pass
00114         self.failUnless(isinstance(marshall, tuple(marshallers)), marshall)
00115 
00116     def testInvokeFactoryWithFileContents(self):
00117         # test for Plone tracker #4939
00118         class fakefile(StringIO.StringIO):
00119             pass
00120         fakefile = fakefile()
00121         fakefile.filename = 'some-filename'
00122         id = self.folder.invokeFactory(self.portal_type,
00123                                        'image.2005-11-18.4066860572',
00124                                        file=fakefile)
00125         self.assertEquals(id, fakefile.filename)
00126 
00127     def testUpperCaseFilename(self):
00128         class fakefile(StringIO.StringIO):
00129             pass
00130         fakefile = fakefile()
00131         fakefile.filename = 'Some-filename-With-Uppercase.txt'
00132         id = 'file.2005-11-18.4066860573'
00133         self.folder.invokeFactory(self.portal_type, id)
00134         self.folder[id].setFile(fakefile)
00135         self.failIf(id in self.folder.objectIds())
00136         self.failUnless(fakefile.filename in self.folder.objectIds())
00137 
00138     def testUpperCaseFilenameWithFunnyCharacters(self):
00139         class fakefile(StringIO.StringIO):
00140             pass
00141         fakefile = fakefile()
00142         fakefile.filename = 'Zope&Plo?ne .txt'
00143         id = 'file.2005-11-18.4066860574'
00144         self.folder.invokeFactory(self.portal_type, id)
00145         self.folder[id].setFile(fakefile)
00146         self.failIf(id in self.folder.objectIds())
00147         self.failUnless('Zope-Plo-ne .txt' in self.folder.objectIds())
00148 
00149     def testWindowsUploadFilename(self):
00150         class fakefile(StringIO.StringIO):
00151             pass
00152         fakefile = fakefile()
00153         fakefile.filename = 'c:\\Windows\\Is\\Worthless\\file.txt'
00154         id = 'file.2005-11-18.4066860574'
00155         self.folder.invokeFactory(self.portal_type, id)
00156         self.folder[id].setFile(fakefile)
00157         self.failIf(id in self.folder.objectIds())
00158         self.failIf(fakefile.filename in self.folder.objectIds())
00159         self.failUnless('file.txt' in self.folder.objectIds())
00160 
00161     def testWindowsDuplicateFiles(self):
00162         class fakefile(StringIO.StringIO):
00163             pass
00164         fakefile = fakefile()
00165         fakefile.filename = 'c:\\Windows\\Is\\Worthless\\file.txt'
00166         id = 'file.2005-11-18.4066860574'
00167         self.folder.invokeFactory(self.portal_type, id)
00168         self.folder[id].setFile(fakefile)
00169         self.folder.invokeFactory(self.portal_type, id)
00170         request = self.folder.REQUEST
00171         request.form['id'] = id
00172         request.form['file_file'] = fakefile
00173         errors = {}
00174         self.folder[id].post_validate(request, errors)
00175         self.failUnless(errors.has_key('file'))
00176 
00177 tests.append(TestSiteATFile)
00178 
00179 class TestATFileFields(atcttestcase.ATCTFieldTestCase):
00180 
00181     # Title is not a required field, since we don't require them 
00182     # on File/Image - they are taken from the filename if not present.
00183     # "Add the comment 'damn stupid fucking test'" -- optilude ;)
00184     def test_title(self):
00185         pass
00186 
00187     def afterSetUp(self):
00188         atcttestcase.ATCTFieldTestCase.afterSetUp(self)
00189         self._dummy = self.createDummy(klass=ATFile)
00190 
00191     def test_fileField(self):
00192         dummy = self._dummy
00193         field = dummy.getField('file')
00194 
00195         self.failUnless(ILayerContainer.isImplementedBy(field))
00196         self.failUnless(field.required == 1, 'Value is %s' % field.required)
00197         self.failUnless(field.default == '', 'Value is %s' % str(field.default))
00198         self.failUnless(field.searchable == True, 'Value is %s' % field.searchable)
00199         self.failUnless(field.vocabulary == (),
00200                         'Value is %s' % str(field.vocabulary))
00201         self.failUnless(field.enforceVocabulary == 0,
00202                         'Value is %s' % field.enforceVocabulary)
00203         self.failUnless(field.multiValued == 0,
00204                         'Value is %s' % field.multiValued)
00205         self.failUnless(field.isMetadata == 0, 'Value is %s' % field.isMetadata)
00206         self.failUnless(field.accessor == 'getFile',
00207                         'Value is %s' % field.accessor)
00208         self.failUnless(field.mutator == 'setFile',
00209                         'Value is %s' % field.mutator)
00210         self.failUnless(field.read_permission == View,
00211                         'Value is %s' % field.read_permission)
00212         self.failUnless(field.write_permission == ModifyPortalContent,
00213                         'Value is %s' % field.write_permission)
00214         self.failUnless(field.generateMode == 'veVc',
00215                         'Value is %s' % field.generateMode)
00216         self.failUnless(field.force == '', 'Value is %s' % field.force)
00217         self.failUnless(field.type == 'file', 'Value is %s' % field.type)
00218         self.failUnless(isinstance(field.storage, AnnotationStorage),
00219                         'Value is %s' % type(field.storage))
00220         self.failUnless(field.getLayerImpl('storage') == AnnotationStorage(migrate=True),
00221                         'Value is %s' % field.getLayerImpl('storage'))
00222         self.failUnless(ILayerContainer.isImplementedBy(field))
00223         self.failUnless(field.validators == "(('isNonEmptyFile', V_REQUIRED), ('checkFileMaxSize', V_REQUIRED))",
00224                         'Value is %s' % str(field.validators))
00225         self.failUnless(isinstance(field.widget, FileWidget),
00226                         'Value is %s' % id(field.widget))
00227         vocab = field.Vocabulary(dummy)
00228         self.failUnless(isinstance(vocab, DisplayList),
00229                         'Value is %s' % type(vocab))
00230         self.failUnless(tuple(vocab) == (), 'Value is %s' % str(tuple(vocab)))
00231         self.failUnless(field.primary == 1, 'Value is %s' % field.primary)
00232 
00233 tests.append(TestATFileFields)
00234 
00235 class TestCleanupFilename(atcttestcase.ATCTSiteTestCase):
00236 
00237     def test_cleanup_filename(self):
00238         self.app.REQUEST.set('HTTP_ACCEPT_LANGUAGE', 'el')
00239         from Products.ATContentTypes.content.base import cleanupFilename
00240         text = unicode('Νίκος Τζάνος', 'utf-8')
00241         self.assertEquals(cleanupFilename(text, request=self.app.REQUEST),
00242                           'Nikos Tzanos')
00243 
00244 tests.append(TestCleanupFilename)
00245 
00246 class TestATFileFunctional(atctftestcase.ATCTIntegrationTestCase):
00247     
00248     portal_type = 'File'
00249     views = ('file_view', 'download', )
00250 
00251     def test_inlineMimetypes_Office(self):
00252         # Only PDF and Office docs are shown inline
00253         self.obj.setFormat('application/msword')
00254         response = self.publish(self.obj_path)
00255         self.assertEqual(response.getStatus(), 200)
00256         self.assertEqual(response.getHeader('Content-Disposition'), None)
00257 
00258         self.obj.setFormat('application/x-msexcel')
00259         response = self.publish(self.obj_path)
00260         self.assertEqual(response.getStatus(), 200)
00261         self.assertEqual(response.getHeader('Content-Disposition'), None)
00262 
00263         self.obj.setFormat('application/vnd.ms-excel')
00264         response = self.publish(self.obj_path)
00265         self.assertEqual(response.getStatus(), 200)
00266         self.assertEqual(response.getHeader('Content-Disposition'), None)
00267 
00268         self.obj.setFormat('application/vnd.ms-powerpoint')
00269         response = self.publish(self.obj_path)
00270         self.assertEqual(response.getStatus(), 200)
00271         self.assertEqual(response.getHeader('Content-Disposition'), None)
00272 
00273     def test_inlineMimetypes_PDF(self):
00274         # Only PDF and Office docs are shown inline
00275         self.obj.setFormat('application/pdf')
00276         response = self.publish(self.obj_path)
00277         self.assertEqual(response.getStatus(), 200)
00278         self.assertEqual(response.getHeader('Content-Disposition'), None)
00279 
00280     def test_inlineMimetypes_Text(self):
00281         # Only PDF and Office docs are shown inline
00282         self.obj.setFilename('foo.txt')
00283         self.obj.setFormat('text/plain')
00284         response = self.publish(self.obj_path)
00285         self.assertEqual(response.getStatus(), 200)
00286         self.assertEqual(response.getHeader('Content-Disposition'), 'attachment; filename="foo.txt"')
00287 
00288     def test_inlineMimetypes_Binary(self):
00289         # Only PDF and Office docs are shown inline
00290         self.obj.setFilename('foo.exe')
00291         self.obj.setFormat('application/octet-stream')
00292         response = self.publish(self.obj_path)
00293         self.assertEqual(response.getStatus(), 200)
00294         self.assertEqual(response.getHeader('Content-Disposition'), 'attachment; filename="foo.exe"')
00295 
00296 tests.append(TestATFileFunctional)
00297 
00298 import unittest
00299 def test_suite():
00300     suite = unittest.TestSuite()
00301     for test in tests:
00302         suite.addTest(unittest.makeSuite(test))
00303     return suite