#
# Tests the ExtFile product
#

import os, sys
if __name__ == '__main__':
    execfile(os.path.join(sys.path[0], 'framework.py'))

from Testing import ZopeTestCase

ZopeTestCase.installProduct('ExtFile')


from Products.ExtFile.tests.ExtFileTestCase import ExtFileTestCase
from Products.ExtFile.tests.ExtFileTestCase import gifImage, jpegImage, notImage
from Products.ExtFile.tests.ExtFileTestCase import copymove_perms
from Products.ExtFile.ExtImage import GENERATE

from cgi import FieldStorage
from ZPublisher.HTTPRequest import FileUpload



class TestExtFileAdd(ExtFileTestCase):
    '''Test ExtFile/ExtImage creation'''

    def testAddFile1(self):
        # Add File from file name
        self.addExtFile(id='file', file=gifImage)
        self.file._finish()
        self.failUnless(self._exists('file.exe'))
        self.assertEqual(self.file.get_size(), self._fsize(gifImage))

    def testAddFile2(self):
        # Add File from file handle
        self.addExtFile(id='file', file=open(gifImage, 'rb'))
        self.file._finish()
        self.failUnless(self._exists('file.exe'))
        self.assertEqual(self.file.get_size(), self._fsize(gifImage))

    def testAddFile3(self):
        # Add File from file upload
        environ = {'REQUEST_METHOD': 'POST', 'CONTENT_TYPE': 'image/gif'}
        file = FileUpload(FieldStorage(fp=open(gifImage, 'rb'), environ=environ))
        self.addExtFile(id='file', file=file)
        self.file._finish()
        self.failUnless(self._exists('file.gif'))
        self.assertEqual(self.file.get_size(), self._fsize(gifImage))

    def testAddImage1(self):
        # Add Image from file name
        self.addExtImage(id='image', file=gifImage)
        self.image._finish()
        self.failUnless(self._exists('image.gif'))
        self.assertEqual(self.image.get_size(), self._fsize(gifImage))

    def testAddImage2(self):
        # Add Image from file handle
        self.addExtImage(id='image', file=open(gifImage, 'rb'))
        self.image._finish()
        self.failUnless(self._exists('image.gif'))
        self.assertEqual(self.image.get_size(), self._fsize(gifImage))

    def testAddImage3(self):
        # Add Image from file upload
        environ = {'REQUEST_METHOD': 'POST', 'CONTENT_TYPE': 'image/gif'}
        file = FileUpload(FieldStorage(fp=open(gifImage, 'rb'), environ=environ))
        self.addExtImage(id='image', file=file)
        self.image._finish()
        self.failUnless(self._exists('image.gif'))
        self.assertEqual(self.image.get_size(), self._fsize(gifImage))



class TestExtFileContentTypes(ExtFileTestCase):
    '''Test ExtFile/ExtImage content-type detection'''

    def testFileContentType0(self):
        # Use default content type
        self.addExtFile(id='file', file=notImage)
        self.file._finish()
        self.assertEqual(self.file.content_type, 'application/octet-stream', 
                         'Content type: ' + self.file.content_type)
        self.failUnless(self._exists('file.exe'))
            
    def testFileContentType1(self):
        # Detect GIF content type from file id
        self.addExtFile(id='file.gif', file=notImage)
        self.file._finish()
        self.assertEqual(self.file.content_type, 'image/gif', 
                         'Content type: ' + self.file.content_type)
        self.failUnless(self._exists('file.gif'))
            
    def testFileContentType2(self):
        # Detect GIF content type from file upload headers
        environ = {'REQUEST_METHOD': 'POST', 'CONTENT_TYPE': 'image/gif'}
        file = FileUpload(FieldStorage(fp=open(notImage, 'rb'), environ=environ))
        self.addExtFile(id='file', file=file)
        self.file._finish()
        self.assertEqual(self.file.content_type, 'image/gif', 
                         'Content type: ' + self.file.content_type)
        self.failUnless(self._exists('file.gif'))

    def testImageContentType0(self):
        # Use default content type
        self.addExtImage(id='image', file=notImage)
        self.image._finish()
        self.assertEqual(self.image.content_type, 'application/octet-stream', 
                         'Content type: ' + self.image.content_type)
        self.failUnless(self._exists('image.exe'))
            
    def testImageContentType1(self):
        # Detect GIF content type from file id
        self.addExtImage(id='image.gif', file=notImage)
        self.image._finish()
        self.assertEqual(self.image.content_type, 'image/gif', 
                         'Content type: ' + self.image.content_type)
        self.failUnless(self._exists('image.gif'))
            
    def testImageContentType2(self):
        # Detect GIF content type from file upload headers
        environ = {'REQUEST_METHOD': 'POST', 'CONTENT_TYPE': 'image/gif'}
        file = FileUpload(FieldStorage(fp=open(notImage, 'rb'), environ=environ))
        self.addExtImage(id='image', file=file)
        self.image._finish()
        self.assertEqual(self.image.content_type, 'image/gif', 
                         'Content type: ' + self.image.content_type)
        self.failUnless(self._exists('image.gif'))

    def testImageContentType3(self):
        # Detect GIF content type from file contents
        self.addExtImage(id='image', file=gifImage)
        self.image._finish()
        self.assertEqual(self.image.content_type, 'image/gif', 
                         'Content type: ' + self.image.content_type)
        self.failUnless(self._exists('image.gif'))
            
    def testImageContentType4(self):
        # Detect JPEG content type from file contents
        self.addExtImage(id='image', file=jpegImage)
        self.image._finish()
        self.assertEqual(self.image.content_type, 'image/jpeg', 
                         'Content type: ' + self.image.content_type)
        self.failUnless(self._exists('image.jpg'))

    def testImageContentType5(self):
        # Detect GIF content type from string buffer
        self.addExtImage(id='image', file=jpegImage)
        self.image.manage_upload(file=open(gifImage, 'rb').read())
        self.image._finish()
        self.assertEqual(self.image.content_type, 'image/gif', 
                         'Content type: ' + self.image.content_type)
        # File is NOT renamed!
        self.failUnless(self._exists('image.jpg')) 
        # Check manage_upload works
        self.assertEqual(self.image.get_size(), self._fsize(gifImage))

    def testImageContentType6(self):
        # Detect JPEG content type from PUT' image
        self.addExtImage(id='image', file=open(gifImage, 'rb'))
        request = self.app.REQUEST
        request['BODYFILE'] = open(jpegImage, 'rb')
        self.image.PUT(request, request.RESPONSE)
        self.image._finish()
        self.assertEqual(self.image.content_type, 'image/jpeg',
                         'Content type: ' + self.image.content_type)
        # File is NOT renamed!
        self.failUnless(self._exists('image.gif')) 
        # Check PUT works
        self.assertEqual(self.image.get_size(), self._fsize(jpegImage))



class TestExtFileRepository(ExtFileTestCase):
    '''Test repository handling'''

    def afterSetUp(self):
        ExtFileTestCase.afterSetUp(self)
        self.folder.manage_addFolder('subfolder')
        self.subfolder = self.folder['subfolder']

    def testName1(self):
        # Create a unique file name
        self.addExtImage(id='image', file=gifImage)
        self.image._finish()
        dispatcher = self.subfolder.manage_addProduct['ExtFile']
        dispatcher.manage_addExtImage(id='image', file=gifImage)
        self.subfolder.image._finish()
        self.failUnless(self._exists('image.gif'))
        self.failIf(self._exists('image.gif.undo'))
        self.failUnless(self._exists('image1.gif'))
        self.failIf(self._exists('image1.gif.undo'))
         
    def testName2(self):
        # Create a unique preview name
        self.addExtImage(id='image', file=jpegImage)
        self.image.manage_create_prev(100, 100, ratio=1)
        self.image._finish()
        self.failUnless(self._exists('image.jpg'))
        self.failIf(self._exists('image.jpg.undo'))
        self.failUnless(self._exists('image1.jpg')) # Generated previews are always jpeg
        self.failIf(self._exists('image1.jpg.undo'))
         
    def testUndoName1(self):
        # Create a .undo file on delete
        self.addExtImage(id='image', file=gifImage)
        self.folder.manage_delObjects(['image'])
        self.failIf(self._exists('image.gif'))
        self.failUnless(self._exists('image.gif.undo'))
         
    def testUndoName2(self):
        # Create a .undo file for the preview image on delete
        self.addExtImage(id='image', file=gifImage)
        self.image.manage_create_prev(100, 100, ratio=1)
        self.image._finish()
        self.failUnless(self._exists('image.gif'))
        self.failUnless(self._exists('image.jpg'))  # Generated previews are always jpeg
        self.folder.manage_delObjects(['image'])
        self.failIf(self._exists('image.gif'))
        self.failUnless(self._exists('image.gif.undo'))
        self.failIf(self._exists('image.jpg'))
        self.failUnless(self._exists('image.jpg.undo'))
         
    def testUndoName3(self):
        # Do not create a .undo file on upload
        self.addExtImage(id='image', file=gifImage)
        self.image.manage_file_upload(gifImage)
        self.image._finish()
        self.failUnless(self._exists('image.gif'))
        self.failIf(self._exists('image.gif.undo'))
        self.failIf(self._exists('image1.gif'))



class TestExtFileCopyPaste(ExtFileTestCase):
    '''Tests cut/copy/paste/rename/clone'''

    def afterSetUp(self):
        ExtFileTestCase.afterSetUp(self)
        self.folder.manage_addFolder('subfolder')
        self.subfolder = self.folder['subfolder']
        self.setPermissions(copymove_perms)
        self.addExtFile(id='image.gif', file=gifImage)
        get_transaction().commit(1) # need a _p_jar

    def testClone(self):
        # Clone a file
        #print self._listdir()
        self.subfolder.manage_clone(self.file, 'image.gif')
        self.file._finish()
        #print self._listdir()
        self.failUnless(self._exists('image.gif'))
        self.failIf(self._exists('image.gif.undo'))
        # XXX: This only works in Zope 2.6+ ???
        #XXX self.failUnless(self._exists('image1.gif'))
        #print self._listdir()
        #print self.image.get_filename()
        #print self.subfolder.image.get_filename()

    def testCopyPaste(self):
        # Copy and paste a file
        cb = self.folder.manage_copyObjects(['image.gif'])
        self.subfolder.manage_pasteObjects(cb)
        self.file._finish()
        self.subfolder['image.gif']._finish()
        self.failUnless(self._exists('image.gif'))
        self.failIf(self._exists('image.gif.undo'))
        self.failUnless(self._exists('image1.gif'))
        self.assertEqual(self.subfolder['image.gif'].get_size(), self._fsize(gifImage))
         
    def testCutPaste(self):
        # Cut and paste a file
        cb = self.folder.manage_cutObjects(['image.gif'])
        self.subfolder.manage_pasteObjects(cb)
        self.file._finish()
        self.subfolder['image.gif']._finish()
        self.failUnless(self._exists('image.gif'))
        self.failIf(self._exists('image.gif.undo'))
        self.failIf(self._exists('image1.gif'))

    def testRename(self):
        # Rename a file
        self.folder.manage_renameObject('image.gif', 'image44.gif')
        self.file._finish()
        self.folder['image44.gif']._finish()
        self.failUnless(self._exists('image.gif'))
        self.failIf(self._exists('image.gif.undo'))
        self.failIf(self._exists('image1.gif'))

    def testCOPY(self):
        # WebDAV copy a file
        req = self.app.REQUEST
        req.environ['HTTP_DEPTH'] = 'infinity'
        req.environ['HTTP_DESTINATION'] = 'http://dummy.org/%s/subfolder/image.gif' % ZopeTestCase.folder_name
        self.folder['image.gif'].COPY(req, req.RESPONSE)
        self.file._finish()
        self.subfolder['image.gif']._finish()
        self.failUnless(self._exists('image.gif'))
        self.failIf(self._exists('image.gif.undo'))
        self.failUnless(self._exists('image1.gif'))
        self.assertEqual(self.subfolder['image.gif'].get_size(), self._fsize(gifImage))
        
    def testMOVE(self):
        # WebDAV move a file
        req = self.app.REQUEST
        req.environ['HTTP_DEPTH'] = 'infinity'
        req.environ['HTTP_DESTINATION'] = 'http://dummy.org/%s/subfolder/image.gif' % ZopeTestCase.folder_name
        self.folder['image.gif'].MOVE(req, req.RESPONSE)
        self.subfolder['image.gif']._finish()
        self.failUnless(self._exists('image.gif'))
        self.failIf(self._exists('image.gif.undo'))
        self.failIf(self._exists('image1.gif'))
        self.failIf(self._exists('image1.gif.undo'))
        self.assertEqual(self.subfolder['image.gif'].get_size(), self._fsize(gifImage))

    def testCopyOfProtection(self):
        # Copy and paste a file into the same folder.
        # The filenames should not begin with 'copy_of_'
        cb = self.folder.manage_copyObjects(['image.gif'])
        self.folder.manage_pasteObjects(cb)
        self.file._finish()
        self.folder['copy_of_image.gif']._finish()
        self.failUnless(self._exists('image.gif'))
        self.failIf(self._exists('image.gif.undo'))
        self.failIf(self._exists('copy_of_image.gif'))
        self.failUnless(self._exists('image1.gif'))
        self.assertEqual(self.folder['copy_of_image.gif'].get_size(), self._fsize(gifImage))



class TestExtImageCopyPaste(ExtFileTestCase):
    '''Tests cut/copy/paste/rename/clone'''

    def afterSetUp(self):
        ExtFileTestCase.afterSetUp(self)
        self.folder.manage_addFolder('subfolder')
        self.subfolder = self.folder['subfolder']
        self.setPermissions(copymove_perms)
        self.addExtImage(id='image.gif', file=gifImage)
        # Add a preview image as well
        self.folder['image.gif'].manage_file_upload(file=jpegImage, is_preview=1)
        get_transaction().commit(1) # need a _p_jar

    def testClone(self):
        # Clone an image
        self.subfolder.manage_clone(self.image, 'image.gif')
        self.image._finish()
        self.failUnless(self._exists('image.gif'))
        self.failIf(self._exists('image.gif.undo'))
        self.failUnless(self._exists('image.jpg'))
        self.failIf(self._exists('image.jpg.undo'))
        # XXX: This only works in Zope 2.6+ ???
        #XXX self.failUnless(self._exists('image2.gif'))
        #XXX self.failUnless(self._exists('image3.gif'))

    def testCopyPaste(self):
        # Copy and paste an image
        cb = self.folder.manage_copyObjects(['image.gif'])
        self.subfolder.manage_pasteObjects(cb)
        self.image._finish()
        self.subfolder['image.gif']._finish()
        self.failUnless(self._exists('image.gif'))
        self.failIf(self._exists('image.gif.undo'))
        self.failUnless(self._exists('image1.gif'))
        self.failIf(self._exists('image1.gif.undo'))
        self.failUnless(self._exists('image.jpg'))
        self.failUnless(self._exists('image1.jpg'))
        self.assertEqual(self.subfolder['image.gif'].get_size(), self._fsize(gifImage))
         
    def testCutPaste(self):
        # Cut and paste an image
        cb = self.folder.manage_cutObjects(['image.gif'])
        self.subfolder.manage_pasteObjects(cb)
        self.image._finish()
        self.subfolder['image.gif']._finish()
        self.failUnless(self._exists('image.gif'))
        self.failIf(self._exists('image.gif.undo'))
        self.failUnless(self._exists('image.jpg'))
        self.failIf(self._exists('image.jpg.undo'))
        self.failIf(self._exists('image1.gif'))
        self.failIf(self._exists('image1.jpg'))

    def testRename(self):
        # Rename an image
        self.folder.manage_renameObject('image.gif', 'image44.gif')
        self.image._finish()
        self.folder['image44.gif']._finish()
        self.failUnless(self._exists('image.gif'))
        self.failIf(self._exists('image.gif.undo'))
        self.failUnless(self._exists('image.jpg'))
        self.failIf(self._exists('image.jpg.undo'))
        self.failIf(self._exists('image1.gif'))
        self.failIf(self._exists('image1.jpg'))

    def testCOPY(self):
        # WebDAV copy an image
        req = self.app.REQUEST
        req.environ['HTTP_DEPTH'] = 'infinity'
        req.environ['HTTP_DESTINATION'] = 'http://dummy.org/%s/subfolder/image.gif' % ZopeTestCase.folder_name
        self.folder['image.gif'].COPY(req, req.RESPONSE)
        self.image._finish()
        self.subfolder['image.gif']._finish()
        self.failUnless(self._exists('image.gif'))
        self.failIf(self._exists('image.gif.undo'))
        self.failUnless(self._exists('image1.gif'))
        self.failIf(self._exists('image1.gif.undo'))
        self.failUnless(self._exists('image.jpg'))
        self.failUnless(self._exists('image1.jpg'))
        self.assertEqual(self.subfolder['image.gif'].get_size(), self._fsize(gifImage))

    def testMOVE(self):
        # WebDAV move an image
        req = self.app.REQUEST
        req.environ['HTTP_DEPTH'] = 'infinity'
        req.environ['HTTP_DESTINATION'] = 'http://dummy.org/%s/subfolder/image.gif' % ZopeTestCase.folder_name
        self.folder['image.gif'].MOVE(req, req.RESPONSE)
        self.subfolder['image.gif']._finish()
        self.failUnless(self._exists('image.gif'))
        self.failIf(self._exists('image.gif.undo'))
        self.failUnless(self._exists('image.jpg'))
        self.failIf(self._exists('image.jpg.undo'))
        self.failIf(self._exists('image1.gif'))
        self.failIf(self._exists('image1.jpg'))
        self.assertEqual(self.subfolder['image.gif'].get_size(), self._fsize(gifImage))

    def testPUTRecreatesPreview(self):
        # PUT an image; the preview should be regenerated.
        self.image._finish()
        self.failUnless(self._exists('image.gif'))
        self.failUnless(self._exists('image.jpg'))  # preview
        self.failIf(self._exists('image.gif.tmp'))
        self.failIf(self._exists('image.jpg.tmp'))
        request = self.app.REQUEST
        request['BODYFILE'] = open(gifImage, 'rb')
        self.image.PUT(request, request.RESPONSE)
        self.failUnless(self._exists('image.gif'))
        self.failUnless(self._exists('image.jpg'))  # preview
        self.failUnless(self._exists('image.gif.tmp'))  # newly put image
        self.failUnless(self._exists('image.jpg.tmp'))  # regenerated preview
        self.image._finish()
        self.failUnless(self._exists('image.gif'))
        self.failUnless(self._exists('image.jpg'))  # regenerated preview
        self.failIf(self._exists('image.gif.tmp'))
        self.failIf(self._exists('image.jpg.tmp'))



def test_suite():
    from unittest import TestSuite, makeSuite
    suite = TestSuite()
    suite.addTest(makeSuite(TestExtFileAdd))
    suite.addTest(makeSuite(TestExtFileContentTypes))
    suite.addTest(makeSuite(TestExtFileRepository))
    suite.addTest(makeSuite(TestExtFileCopyPaste))
    suite.addTest(makeSuite(TestExtImageCopyPaste))
    return suite

if __name__ == '__main__':
    framework()

