[BUGFIX] Create upload folder on extension install
authorHelmut Hummel <helmut.hummel@typo3.org>
Sat, 20 Oct 2012 13:44:09 +0000 (15:44 +0200)
committerHelmut Hummel <helmut.hummel@typo3.org>
Sat, 20 Oct 2012 20:22:49 +0000 (22:22 +0200)
Implement the creation of configured upload folder
and "createDirs".

Releases: 6.0
Resolves: #42145

Change-Id: I4951d6daa6c3c8981f03b3d77a56e5f48913a5a5
Reviewed-on: http://review.typo3.org/15838
Reviewed-by: Wouter Wolters
Tested-by: Wouter Wolters
Reviewed-by: Helmut Hummel
Tested-by: Helmut Hummel
typo3/sysext/extensionmanager/Classes/Utility/FileHandlingUtility.php
typo3/sysext/extensionmanager/Classes/Utility/InstallUtility.php
typo3/sysext/extensionmanager/Tests/Unit/Utility/FileHandlingUtilityTest.php
typo3/sysext/extensionmanager/Tests/Unit/Utility/InstallUtilityTest.php
typo3/sysext/extensionmanager/ext_emconf.php

index 8636ba2..2f01e95 100644 (file)
@@ -1,5 +1,6 @@
 <?php
 namespace TYPO3\CMS\Extensionmanager\Utility;
+use \TYPO3\CMS\Core\Utility\GeneralUtility;
 
 /***************************************************************
  *  Copyright notice
@@ -117,11 +118,26 @@ class FileHandlingUtility implements \TYPO3\CMS\Core\SingletonInterface {
         */
        protected function createDirectoriesForExtensionFiles(array $directories, $rootPath) {
                foreach ($directories as $directory) {
-                       \TYPO3\CMS\Core\Utility\GeneralUtility::mkdir_deep($rootPath . $directory);
+                       $this->createNestedDirectory($rootPath . $directory);
                }
        }
 
        /**
+        * Wrapper for utility method to create directory recusively
+        *
+        * @param string $directory Absolute path
+        * @throws \TYPO3\CMS\Extensionmanager\Exception\ExtensionManagerException
+        */
+       protected function createNestedDirectory($directory) {
+               try {
+                       GeneralUtility::mkdir_deep($directory);
+               } catch(\RuntimeException $exception) {
+                       throw new \TYPO3\CMS\Extensionmanager\Exception\ExtensionManagerException(sprintf($GLOBALS['LANG']->getLL('clearMakeExtDir_could_not_create_dir'), $this->getRelativePath($directory)), 1337280416);
+               }
+
+       }
+
+       /**
         * Loops over an array of files and writes them to the given rootPath
         *
         * @param array $files
@@ -130,7 +146,7 @@ class FileHandlingUtility implements \TYPO3\CMS\Core\SingletonInterface {
         */
        protected function writeExtensionFiles(array $files, $rootPath) {
                foreach ($files as $file) {
-                       \TYPO3\CMS\Core\Utility\GeneralUtility::writeFile($rootPath . $file['name'], $file['content']);
+                       GeneralUtility::writeFile($rootPath . $file['name'], $file['content']);
                }
        }
 
@@ -147,7 +163,7 @@ class FileHandlingUtility implements \TYPO3\CMS\Core\SingletonInterface {
                $paths = \TYPO3\CMS\Extensionmanager\Domain\Model\Extension::returnInstallPaths();
                $path = $paths[$pathType];
                if (!$path || !is_dir($path) || !$extensionkey) {
-                       throw new \TYPO3\CMS\Extensionmanager\Exception\ExtensionManagerException(sprintf('ERROR: The extension install path "%s" was no directory!', $path), 1337280417);
+                       throw new \TYPO3\CMS\Extensionmanager\Exception\ExtensionManagerException(sprintf('ERROR: The extension install path "%s" was no directory!', $this->getRelativePath($path)), 1337280417);
                } else {
                        $extDirPath = $path . $extensionkey . '/';
                        if (is_dir($extDirPath)) {
@@ -166,13 +182,69 @@ class FileHandlingUtility implements \TYPO3\CMS\Core\SingletonInterface {
         * @return void
         */
        protected function addDirectory($extDirPath) {
-               \TYPO3\CMS\Core\Utility\GeneralUtility::mkdir($extDirPath);
+               GeneralUtility::mkdir($extDirPath);
                if (!is_dir($extDirPath)) {
-                       throw new \TYPO3\CMS\Extensionmanager\Exception\ExtensionManagerException(sprintf($GLOBALS['LANG']->getLL('clearMakeExtDir_could_not_create_dir'), $extDirPath), 1337280416);
+                       throw new \TYPO3\CMS\Extensionmanager\Exception\ExtensionManagerException(sprintf($GLOBALS['LANG']->getLL('clearMakeExtDir_could_not_create_dir'), $this->getRelativePath($extDirPath)), 1337280416);
                }
        }
 
        /**
+        * Creates directories configured in ext_emconf.php if not already present
+        *
+        * @param array $extension
+        */
+       public function ensureConfiguredDirectoriesExist(array $extension) {
+               foreach ($this->getAbsolutePathsToConfiguredDirectories($extension) as $directory) {
+                       if (!$this->directoryExists($directory)) {
+                               $this->createNestedDirectory($directory);
+                       }
+               }
+       }
+
+       /**
+        * Wrapper method for directory existance check
+        *
+        * @param string $directory
+        * @return boolean
+        */
+       protected function directoryExists($directory) {
+               return is_dir($directory);
+       }
+
+       /**
+        * Checks configuration and returns an array of absolute paths that should be created
+        *
+        * @param array $extension
+        * @return array
+        */
+       protected function getAbsolutePathsToConfiguredDirectories(array $extension) {
+               $requestedDirectories = array();
+               $requestUploadFolder = isset($extension['uploadfolder']) ? (boolean)$extension['uploadfolder'] : FALSE;
+               if ($requestUploadFolder) {
+                       $requestedDirectories[] = $this->getAbsolutePath($this->getPathToUploadFolder($extension));
+               }
+
+               $requestCreateDirectories = empty($extension['createDirs']) ? FALSE : (string)$extension['createDirs'];
+               if ($requestCreateDirectories) {
+                       foreach (GeneralUtility::trimExplode(',', $extension['createDirs']) as $directoryToCreate) {
+                               $requestedDirectories[] = $this->getAbsolutePath($directoryToCreate);
+                       }
+               }
+
+               return $requestedDirectories;
+       }
+
+       /**
+        * Upload folders always reside in “uploads/tx_[extKey-with-no-underscore]”
+        *
+        * @param array $extension
+        * @return string
+        */
+       protected function getPathToUploadFolder($extension) {
+               return 'uploads/tx_' . str_replace('_', '', $extension['key']) . '/';
+       }
+
+       /**
         * Remove specified directory
         *
         * @param string $extDirPath
@@ -180,9 +252,9 @@ class FileHandlingUtility implements \TYPO3\CMS\Core\SingletonInterface {
         * @return void
         */
        public function removeDirectory($extDirPath) {
-               $res = \TYPO3\CMS\Core\Utility\GeneralUtility::rmdir($extDirPath, TRUE);
+               $res = GeneralUtility::rmdir($extDirPath, TRUE);
                if ($res === FALSE) {
-                       throw new \TYPO3\CMS\Extensionmanager\Exception\ExtensionManagerException(sprintf($GLOBALS['LANG']->getLL('clearMakeExtDir_could_not_remove_dir'), $extDirPath), 1337280415);
+                       throw new \TYPO3\CMS\Extensionmanager\Exception\ExtensionManagerException(sprintf($GLOBALS['LANG']->getLL('clearMakeExtDir_could_not_remove_dir'), $this->getRelativePath($extDirPath)), 1337280415);
                }
        }
 
@@ -196,7 +268,7 @@ class FileHandlingUtility implements \TYPO3\CMS\Core\SingletonInterface {
         */
        protected function writeEmConfToFile(array $extensionData, $rootPath, \TYPO3\CMS\Extensionmanager\Domain\Model\Extension $extension = NULL) {
                $emConfContent = $this->emConfUtility->constructEmConf($extensionData, $extension);
-               \TYPO3\CMS\Core\Utility\GeneralUtility::writeFile($rootPath . 'ext_emconf.php', $emConfContent);
+               GeneralUtility::writeFile($rootPath . 'ext_emconf.php', $emConfContent);
        }
 
        /**
@@ -208,7 +280,7 @@ class FileHandlingUtility implements \TYPO3\CMS\Core\SingletonInterface {
        public function isValidExtensionPath($path) {
                $allowedPaths = \TYPO3\CMS\Extensionmanager\Domain\Model\Extension::returnAllowedInstallPaths();
                foreach ($allowedPaths as $allowedPath) {
-                       if (\TYPO3\CMS\Core\Utility\GeneralUtility::isFirstPartOfStr($path, $allowedPath)) {
+                       if (GeneralUtility::isFirstPartOfStr($path, $allowedPath)) {
                                return TRUE;
                        }
                }
@@ -221,8 +293,22 @@ class FileHandlingUtility implements \TYPO3\CMS\Core\SingletonInterface {
         * @param string $relativePath
         * @return string
         */
-       public function returnAbsolutePath($relativePath) {
-               return \TYPO3\CMS\Core\Utility\GeneralUtility::resolveBackPath(PATH_site . $relativePath);
+       protected function getAbsolutePath($relativePath) {
+               $absolutePath = GeneralUtility::getFileAbsFileName(GeneralUtility::resolveBackPath(PATH_site . $relativePath));
+               if (empty($absolutePath)) {
+                       throw new \TYPO3\CMS\Extensionmanager\Exception\ExtensionManagerException('Illegal relative path given', 1350742864);
+               }
+               return $absolutePath;
+       }
+
+       /**
+        * Returns relative path
+        *
+        * @param string $absolutePath
+        * @return string
+        */
+       protected function getRelativePath($absolutePath) {
+               return substr($absolutePath, strlen(PATH_site));
        }
 
        /**
@@ -233,7 +319,7 @@ class FileHandlingUtility implements \TYPO3\CMS\Core\SingletonInterface {
         */
        public function getAbsoluteExtensionPath($extension) {
                $extension = $this->installUtility->enrichExtensionWithDetails($extension);
-               $absolutePath = $this->returnAbsolutePath($extension['siteRelPath']);
+               $absolutePath = $this->getAbsolutePath($extension['siteRelPath']);
                return $absolutePath;
        }
 
@@ -258,7 +344,7 @@ class FileHandlingUtility implements \TYPO3\CMS\Core\SingletonInterface {
        public function createZipFileFromExtension($extension) {
                $extensionPath = $this->getAbsoluteExtensionPath($extension);
                $version = $this->getExtensionVersion($extension);
-               $fileName = PATH_site . 'typo3temp/' . $extension . '_' . $version . '.zip';
+               $fileName = $this->getAbsolutePath('typo3temp/' . $extension . '_' . $version . '.zip');
                $zip = new \ZipArchive();
                $zip->open($fileName, \ZipArchive::CREATE);
                $iterator = new \RecursiveIteratorIterator(new \RecursiveDirectoryIterator($extensionPath));
@@ -293,20 +379,20 @@ class FileHandlingUtility implements \TYPO3\CMS\Core\SingletonInterface {
                                        $dir = substr(zip_entry_name($zipEntry), 0, $last);
                                        $file = substr(zip_entry_name($zipEntry), strrpos(zip_entry_name($zipEntry), DIRECTORY_SEPARATOR) + 1);
                                        if (!is_dir($dir)) {
-                                               \TYPO3\CMS\Core\Utility\GeneralUtility::mkdir_deep($extensionDir . $dir);
+                                               GeneralUtility::mkdir_deep($extensionDir . $dir);
                                        }
                                        if (strlen(trim($file)) > 0) {
-                                               $return = \TYPO3\CMS\Core\Utility\GeneralUtility::writeFile($extensionDir . $dir . '/' . $file, zip_entry_read($zipEntry, zip_entry_filesize($zipEntry)));
+                                               $return = GeneralUtility::writeFile($extensionDir . $dir . '/' . $file, zip_entry_read($zipEntry, zip_entry_filesize($zipEntry)));
                                                if ($return === FALSE) {
-                                                       throw new \TYPO3\CMS\Extensionmanager\Exception\ExtensionManagerException('Could not write file ' . $file, 1344691048);
+                                                       throw new \TYPO3\CMS\Extensionmanager\Exception\ExtensionManagerException('Could not write file ' . $this->getRelativePath($file), 1344691048);
                                                }
                                        }
                                } else {
-                                       \TYPO3\CMS\Core\Utility\GeneralUtility::writeFile($extensionDir . zip_entry_name($zipEntry), zip_entry_read($zipEntry, zip_entry_filesize($zipEntry)));
+                                       GeneralUtility::writeFile($extensionDir . zip_entry_name($zipEntry), zip_entry_read($zipEntry, zip_entry_filesize($zipEntry)));
                                }
                        }
                } else {
-                       throw new \TYPO3\CMS\Extensionmanager\Exception\ExtensionManagerException('Unable to open zip file ' . $file, 1344691049);
+                       throw new \TYPO3\CMS\Extensionmanager\Exception\ExtensionManagerException('Unable to open zip file ' . $this->getRelativePath($file), 1344691049);
                }
        }
 
index f901963..b81a384 100644 (file)
@@ -53,7 +53,7 @@ class InstallUtility implements \TYPO3\CMS\Core\SingletonInterface {
        /**
         * @var \TYPO3\CMS\Extensionmanager\Utility\FileHandlingUtility
         */
-       protected $filehandlingUtility;
+       protected $fileHandlingUtility;
 
        /**
         * @var \TYPO3\CMS\Extensionmanager\Utility\ListUtility
@@ -87,8 +87,8 @@ class InstallUtility implements \TYPO3\CMS\Core\SingletonInterface {
         * @param \TYPO3\CMS\Extensionmanager\Utility\FileHandlingUtility $filehandlingUtility
         * @return void
         */
-       public function injectFilehandlingUtility(\TYPO3\CMS\Extensionmanager\Utility\FileHandlingUtility $filehandlingUtility) {
-               $this->filehandlingUtility = $filehandlingUtility;
+       public function injectFileHandlingUtility(\TYPO3\CMS\Extensionmanager\Utility\FileHandlingUtility $fileHandlingUtility) {
+               $this->fileHandlingUtility = $fileHandlingUtility;
        }
 
        /**
@@ -157,7 +157,6 @@ class InstallUtility implements \TYPO3\CMS\Core\SingletonInterface {
         * Wrapper function for unloading extensions
         *
         * @param string $extensionKey
-        * @return void
         */
        protected function unloadExtension($extensionKey) {
                \TYPO3\CMS\Core\Extension\ExtensionManager::unloadExtension($extensionKey);
@@ -174,6 +173,7 @@ class InstallUtility implements \TYPO3\CMS\Core\SingletonInterface {
        public function install($extensionKey) {
                $extension = $this->enrichExtensionWithDetails($extensionKey);
                $this->processDatabaseUpdates($extension);
+               $this->ensureConfiguredDirectoriesExist($extension);
                if ($extension['clearcacheonload']) {
                        $GLOBALS['typo3CacheManager']->flushCaches();
                }
@@ -196,8 +196,8 @@ class InstallUtility implements \TYPO3\CMS\Core\SingletonInterface {
         * Fetch additional information for an extension key
         *
         * @param string $extensionKey
-        * @internal
-        * @return mixed
+        * @access private
+        * @return array
         * @throws \TYPO3\CMS\Extensionmanager\Exception\ExtensionManagerException
         */
        public function enrichExtensionWithDetails($extensionKey) {
@@ -212,13 +212,21 @@ class InstallUtility implements \TYPO3\CMS\Core\SingletonInterface {
        }
 
        /**
+        * Creates directories as requested in ext_emconf.php
+        *
+        * @param array $extension
+        */
+       protected function ensureConfiguredDirectoriesExist(array $extension) {
+               $this->fileHandlingUtility->ensureConfiguredDirectoriesExist($extension);
+       }
+
+       /**
         * Gets the content of the ext_tables.sql and ext_tables_static+adt.sql files
         * Additionally adds the table definitions for the cache tables
         *
-        * @param string $extension
-        * @return void
+        * @param array $extension
         */
-       public function processDatabaseUpdates($extension) {
+       public function processDatabaseUpdates(array $extension) {
                $extTablesSqlFile = PATH_site . $extension['siteRelPath'] . '/ext_tables.sql';
                if (file_exists($extTablesSqlFile)) {
                        $extTablesSqlContent = \TYPO3\CMS\Core\Utility\GeneralUtility::getUrl($extTablesSqlFile);
@@ -327,9 +335,9 @@ class InstallUtility implements \TYPO3\CMS\Core\SingletonInterface {
         * @return void
         */
        public function removeExtension($extension) {
-               $absolutePath = $this->filehandlingUtility->getAbsoluteExtensionPath($extension);
-               if ($this->filehandlingUtility->isValidExtensionPath($absolutePath)) {
-                       $this->filehandlingUtility->removeDirectory($absolutePath);
+               $absolutePath = $this->fileHandlingUtility->getAbsoluteExtensionPath($extension);
+               if ($this->fileHandlingUtility->isValidExtensionPath($absolutePath)) {
+                       $this->fileHandlingUtility->removeDirectory($absolutePath);
                } else {
                        throw new \TYPO3\CMS\Extensionmanager\Exception\ExtensionManagerException('No valid extension path given.', 1342875724);
                }
index 8f73402..7b58dc6 100644 (file)
@@ -80,6 +80,50 @@ class FileHandlingUtilityTest extends \TYPO3\CMS\Extbase\Tests\Unit\BaseTestCase
        }
 
        /**
+        * @return array
+        */
+       public function invalidRelativePathDataProvider() {
+               return array(
+                       array('../../'),
+                       array('/foo/bar'),
+                       array('foo//bar'),
+                       array('foo/bar' . chr(0)),
+               );
+       }
+
+       /**
+        * @param string $invalidRelativePath
+        * @test
+        * @dataProvider invalidRelativePathDataProvider
+        * @expectedException \TYPO3\CMS\Extensionmanager\Exception\ExtensionManagerException
+        */
+       public function getAbsolutePathThrowsExceptionForInvalidRelativePaths($invalidRelativePath) {
+               $fileHandlerMock = $this->getAccessibleMock('TYPO3\\CMS\\Extensionmanager\\Utility\\FileHandlingUtility', array('dummy'));
+               $fileHandlerMock->_call('getAbsolutePath', $invalidRelativePath);
+       }
+
+       /**
+        * @return array
+        */
+       public function validRelativePathDataProvider() {
+               return array(
+                       array('foo/../bar', PATH_site . 'bar'),
+                       array('bas', PATH_site . 'bas'),
+               );
+       }
+
+       /**
+        * @param string $validRelativePath
+        * @param string $expectedAbsolutePath
+        * @test
+        * @dataProvider validRelativePathDataProvider
+        */
+       public function getAbsolutePathReturnsAbsolutePathForValidRelativePaths($validRelativePath, $expectedAbsolutePath) {
+               $fileHandlerMock = $this->getAccessibleMock('TYPO3\\CMS\\Extensionmanager\\Utility\\FileHandlingUtility', array('dummy'));
+               $this->assertSame($expectedAbsolutePath, $fileHandlerMock->_call('getAbsolutePath', $validRelativePath));
+       }
+
+       /**
         * @test
         * @return void
         */
@@ -260,7 +304,99 @@ class FileHandlingUtilityTest extends \TYPO3\CMS\Extbase\Tests\Unit\BaseTestCase
                $this->assertTrue(file_exists($rootPath . 'ext_emconf.php'));
        }
 
-}
+       /**
+        * @return \PHPUnit_Framework_MockObject_MockObject|\TYPO3\CMS\Extensionmanager\Utility\FileHandlingUtility
+        */
+       protected function getPreparedFileHandlingMockForDirectoryCreationTests() {
+               /** @var $fileHandlerMock \TYPO3\CMS\Extensionmanager\Utility\FileHandlingUtility|\PHPUnit_Framework_MockObject_MockObject */
+               $fileHandlerMock = $this->getMock('TYPO3\\CMS\\Extensionmanager\\Utility\\FileHandlingUtility', array('createNestedDirectory', 'getAbsolutePath', 'directoryExists'));
+               $fileHandlerMock->expects($this->any())
+                       ->method('getAbsolutePath')
+                       ->will($this->returnArgument(0));
+               return $fileHandlerMock;
+       }
 
+       /**
+        * @test
+        */
+       public function uploadFolderIsNotCreatedIfNotRequested() {
+               $fileHandlerMock = $this->getPreparedFileHandlingMockForDirectoryCreationTests();
+               $fileHandlerMock->expects($this->never())
+                       ->method('createNestedDirectory');
+               $fileHandlerMock->ensureConfiguredDirectoriesExist(array(
+                               'key' => 'foo_bar',
+                               'uploadfolder' => 0,
+                       )
+               );
+       }
+
+       /**
+        * @test
+        */
+       public function additionalFoldersAreNotCreatedIfNotRequested() {
+               $fileHandlerMock = $this->getPreparedFileHandlingMockForDirectoryCreationTests();
+               $fileHandlerMock->expects($this->never())
+                       ->method('createNestedDirectory');
+               $fileHandlerMock->ensureConfiguredDirectoriesExist(array(
+                               'key' => 'foo_bar',
+                               'createDirs' => '',
+                       )
+               );
+       }
+
+       /**
+        * @test
+        */
+       public function configuredUploadFolderIsCreatedIfRequested() {
+               $fileHandlerMock = $this->getPreparedFileHandlingMockForDirectoryCreationTests();
+               $fileHandlerMock->expects($this->once())
+                       ->method('createNestedDirectory')
+                       ->with('uploads/tx_foobar/');
+               $fileHandlerMock->ensureConfiguredDirectoriesExist(array(
+                               'key' => 'foo_bar',
+                               'uploadfolder' => 1,
+                       )
+               );
+       }
+
+       /**
+        * @test
+        */
+       public function configuredAdditionalDirectoriesAreCreatedIfRequested() {
+               $fileHandlerMock = $this->getPreparedFileHandlingMockForDirectoryCreationTests();
+               $fileHandlerMock->expects($this->exactly(2))
+                       ->method('createNestedDirectory')
+                       ->will($this->returnCallback(function($path) {
+                                       if (!in_array($path, array('foo/bar', 'baz/foo'))) {
+                                               throw new \Exception('Path "' . $path . '" is not expected to be created');
+                                       }
+
+                               })
+                       );
+               $fileHandlerMock->ensureConfiguredDirectoriesExist(array(
+                               'key' => 'foo_bar',
+                               'createDirs' => 'foo/bar, baz/foo',
+                       )
+               );
+       }
+
+       /**
+        * @test
+        */
+       public function configuredDirectoriesAreNotCreatedIfTheyAlreadyExist() {
+               $fileHandlerMock = $this->getPreparedFileHandlingMockForDirectoryCreationTests();
+               $fileHandlerMock->expects($this->exactly(3))
+                       ->method('directoryExists')
+                       ->will($this->returnValue(TRUE));
+               $fileHandlerMock->expects($this->never())
+                       ->method('createNestedDirectory');
+               $fileHandlerMock->ensureConfiguredDirectoriesExist(array(
+                               'key' => 'foo_bar',
+                               'uploadfolder' => 1,
+                               'createDirs' => 'foo/bar, baz/foo',
+                       )
+               );
+       }
+}
 
 ?>
\ No newline at end of file
index b9298be..83af0e4 100644 (file)
@@ -31,12 +31,15 @@ namespace TYPO3\CMS\Extensionmanager\Tests\Unit\Utility;
  * @subpackage Tests
  */
 class InstallUtilityTest extends \TYPO3\CMS\Extbase\Tests\Unit\BaseTestCase {
+       /**
+        * @var string
+        */
+       protected $extensionKey;
 
-       public $extListGlobal;
-
-       public $loadedExtGlobal;
-
-       public $extension;
+       /**
+        * @var array
+        */
+       protected $extensionData = array();
 
        /**
         * @var array List of created fake extensions to be deleted in tearDown() again
@@ -44,25 +47,38 @@ class InstallUtilityTest extends \TYPO3\CMS\Extbase\Tests\Unit\BaseTestCase {
        protected $fakedExtensions = array();
 
        /**
-        * @var \TYPO3\CMS\Extensionmanager\Utility\InstallUtility
+        * @var \PHPUnit_Framework_MockObject_MockObject|\TYPO3\CMS\Extensionmanager\Utility\InstallUtility
         */
-       public $installMock;
-
-       protected $listUtilityMock;
+       protected $installMock;
 
        /**
         * @return void
         */
        public function setUp() {
-               $this->extension = 'dummy';
+               $this->extensionKey = 'dummy';
+               $this->extensionData = array(
+                       'key' => $this->extensionKey
+               );
                $this->installMock = $this->getAccessibleMock('TYPO3\\CMS\\Extensionmanager\\Utility\\InstallUtility', array(
                        'loadExtension',
                        'unloadExtension',
                        'processDatabaseUpdates',
                        'reloadCaches',
                        'saveDefaultConfiguration',
-                       'enrichExtensionWithDetails'
+                       'enrichExtensionWithDetails',
+                       'ensureConfiguredDirectoriesExist',
                ));
+               $this->installMock->expects($this->any())
+                               ->method('enrichExtensionWithDetails')
+                               ->with($this->extensionKey)
+                               ->will($this->returnCallback(array($this, 'getExtensionData')));
+       }
+
+       /**
+        * @return array
+        */
+       public function getExtensionData() {
+               return $this->extensionData;
        }
 
        /**
@@ -93,69 +109,67 @@ class InstallUtilityTest extends \TYPO3\CMS\Extbase\Tests\Unit\BaseTestCase {
 
        /**
         * @test
-        * @return void
         */
        public function installCallsProcessDatabaseUpdates() {
-               $this->installMock->expects($this->once())->method('enrichExtensionWithDetails')->with($this->extension)->will($this->returnValue(array('key' => $this->extension)));
-               $this->installMock->expects($this->once())->method('processDatabaseUpdates')->with(array('key' => $this->extension));
-               $this->installMock->install($this->extension);
+               $this->installMock->expects($this->once())
+                               ->method('processDatabaseUpdates')
+                               ->with($this->extensionData);
+
+               $this->installMock->install($this->extensionKey);
        }
 
        /**
         * @test
-        * @return void
         */
        public function installCallsLoadExtenion() {
-               $this->installMock->expects($this->once())->method('enrichExtensionWithDetails')->with($this->extension)->will($this->returnValue(array('key' => $this->extension)));
                $this->installMock->expects($this->once())->method('loadExtension');
-               $this->installMock->install($this->extension);
+               $this->installMock->install($this->extensionKey);
        }
 
        /**
         * @test
-        * @return void
         */
        public function installCallsFlushCachesIfClearCacheOnLoadIsSet() {
-               $this->installMock->expects($this->once())->method('enrichExtensionWithDetails')->with($this->extension)->will($this->returnValue(array('key' => $this->extension, 'clearcacheonload' => TRUE)));
-               $backupCacheManager = $GLOBALS['typo3CacheManager'];
+               $this->extensionData['clearcacheonload'] = TRUE;
                $GLOBALS['typo3CacheManager'] = $this->getMock('TYPO3\\CMS\\Core\\Cache\\CacheManager');
                $GLOBALS['typo3CacheManager']->expects($this->once())->method('flushCaches');
-               $this->installMock->install($this->extension);
-               $GLOBALS['typo3CacheManager'] = $backupCacheManager;
+               $this->installMock->install($this->extensionKey);
+       }
+
+       /**
+        * @test
+        */
+       public function installationOfAnExtensionWillCallEnsureThatDirectoriesExist() {
+               $this->installMock->expects($this->once())->method('ensureConfiguredDirectoriesExist');
+               $this->installMock->install($this->extensionKey);
        }
 
        /**
         * @test
-        * @return void
         */
        public function installCallsReloadCaches() {
-               $this->installMock->expects($this->once())->method('enrichExtensionWithDetails')->with($this->extension)->will($this->returnValue(array('key' => $this->extension)));
                $this->installMock->expects($this->once())->method('reloadCaches');
                $this->installMock->install('dummy');
        }
 
        /**
         * @test
-        * @return void
         */
        public function installCallsSaveDefaultConfigurationWithExtensionKey() {
-               $this->installMock->expects($this->once())->method('enrichExtensionWithDetails')->with($this->extension)->will($this->returnValue(array('key' => $this->extension)));
                $this->installMock->expects($this->once())->method('saveDefaultConfiguration')->with('dummy');
                $this->installMock->install('dummy');
        }
 
        /**
         * @test
-        * @return void
         */
        public function uninstallCallsUnloadExtension() {
                $this->installMock->expects($this->once())->method('unloadExtension');
-               $this->installMock->uninstall('dummy');
+               $this->installMock->uninstall($this->extensionKey);
        }
 
        /**
         * @test
-        * @return void
         */
        public function processDatabaseUpdatesCallsUpdateDbWithExtTablesSql() {
                $extKey = $this->createFakeExtension();
@@ -170,7 +184,6 @@ class InstallUtilityTest extends \TYPO3\CMS\Extbase\Tests\Unit\BaseTestCase {
 
        /**
         * @test
-        * @return void
         */
        public function processDatabaseUpdatesCallsUpdateDbWithExtTablesSqlIncludingCachingFrameworkTables() {
                $extKey = $this->createFakeExtension();
@@ -185,7 +198,6 @@ class InstallUtilityTest extends \TYPO3\CMS\Extbase\Tests\Unit\BaseTestCase {
 
        /**
         * @test
-        * @return void
         */
        public function processDatabaseUpdatesCallsImportStaticSql() {
                $extKey = $this->createFakeExtension();
@@ -197,8 +209,5 @@ class InstallUtilityTest extends \TYPO3\CMS\Extbase\Tests\Unit\BaseTestCase {
                $installMock->expects($this->once())->method('importStaticSql')->with($fileContent);
                $installMock->processDatabaseUpdates($this->fakedExtensions[$extKey]);
        }
-
 }
-
-
 ?>
\ No newline at end of file
index a4bdd4c..9e5fc89 100644 (file)
@@ -18,7 +18,6 @@ $EM_CONF[$_EXTKEY] = array(
        'priority' => '',
        'loadOrder' => '',
        'module' => 'classes',
-       'doNotLoadInFE' => 1,
        'state' => 'stable',
        'internal' => 0,
        'uploadfolder' => 0,