[TASK] Add unit tests for FilesContentObject 16/24816/3
authorNicole Cordes <typo3@cordes.co>
Tue, 15 Oct 2013 15:04:29 +0000 (17:04 +0200)
committerWouter Wolters <typo3@wouterwolters.nl>
Thu, 17 Oct 2013 19:41:22 +0000 (21:41 +0200)
This patch adds unit tests and some small bug fixes for
TYPO3\CMS\Frontend\ContentObject\FilesContentObject class.

Resolves: #52864
Releases: 6.2
Change-Id: I871844518aed876fca0b378d91209eb568c1561b
Reviewed-on: https://review.typo3.org/24816
Reviewed-by: Christian Kuhn
Tested-by: Christian Kuhn
Reviewed-by: Wouter Wolters
Tested-by: Wouter Wolters
typo3/sysext/frontend/Classes/ContentObject/FilesContentObject.php
typo3/sysext/frontend/Tests/Unit/ContentObject/FilesContentObjectTest.php [new file with mode: 0644]

index 2b2f362..509a229 100644 (file)
@@ -37,6 +37,21 @@ use TYPO3\CMS\Core\Utility\MathUtility;
  */
 class FilesContentObject extends \TYPO3\CMS\Frontend\ContentObject\AbstractContentObject {
 
+       /**
+        * @var \TYPO3\CMS\Core\Resource\FileCollectionRepository|NULL
+        */
+       protected $collectionRepository = NULL;
+
+       /**
+        * @var \TYPO3\CMS\Core\Resource\ResourceFactory|NULL
+        */
+       protected $fileFactory = NULL;
+
+       /**
+        * @var \TYPO3\CMS\Core\Resource\FileRepository|NULL
+        */
+       protected $fileRepository = NULL;
+
        /**
         * Rendering the cObject FILES
         *
@@ -44,8 +59,6 @@ class FilesContentObject extends \TYPO3\CMS\Frontend\ContentObject\AbstractConte
         * @return string Output
         */
        public function render($conf = array()) {
-               /** @var \TYPO3\CMS\Core\Resource\FileRepository $fileRepository */
-               $fileRepository = GeneralUtility::makeInstance('TYPO3\\CMS\\Core\\Resource\\FileRepository');
                $fileObjects = array();
                // Getting the files
                if ($conf['references'] || $conf['references.']) {
@@ -62,7 +75,7 @@ class FilesContentObject extends \TYPO3\CMS\Frontend\ContentObject\AbstractConte
                        $referencesUidArray = GeneralUtility::intExplode(',', $referencesUid, TRUE);
                        foreach ($referencesUidArray as $referenceUid) {
                                try {
-                                       $this->addToArray($fileRepository->findFileReferenceByUid($referenceUid), $fileObjects);
+                                       $this->addToArray($this->getFileRepository()->findFileReferenceByUid($referenceUid), $fileObjects);
                                } catch (\TYPO3\CMS\Core\Resource\Exception $e) {
                                        /** @var \TYPO3\CMS\Core\Log\Logger $logger */
                                        $logger = GeneralUtility::makeInstance('TYPO3\CMS\Core\Log\LogManager')->getLogger();
@@ -71,15 +84,17 @@ class FilesContentObject extends \TYPO3\CMS\Frontend\ContentObject\AbstractConte
                        }
 
                        // It's important that this always stays "fieldName" and not be renamed to "field" as it would otherwise collide with the stdWrap key of that name
-                       $referencesFieldName = $this->stdWrapValue('fieldName', $conf['references.']);
-                       if ($referencesFieldName) {
-                               $table = $this->cObj->getCurrentTable();
-                               if ($table === 'pages' && isset($this->cObj->data['_LOCALIZED_UID']) && intval($this->cObj->data['sys_language_uid']) > 0) {
-                                       $table = 'pages_language_overlay';
+                       if (!empty($conf['references.'])) {
+                               $referencesFieldName = $this->stdWrapValue('fieldName', $conf['references.']);
+                               if ($referencesFieldName) {
+                                       $table = $this->cObj->getCurrentTable();
+                                       if ($table === 'pages' && isset($this->cObj->data['_LOCALIZED_UID']) && intval($this->cObj->data['sys_language_uid']) > 0) {
+                                               $table = 'pages_language_overlay';
+                                       }
+                                       $referencesForeignTable = $this->stdWrapValue('table', $conf['references.'], $table);
+                                       $referencesForeignUid = $this->stdWrapValue('uid', $conf['references.'], isset($this->cObj->data['_LOCALIZED_UID']) ? $this->cObj->data['_LOCALIZED_UID'] : $this->cObj->data['uid']);
+                                       $this->addToArray($this->getFileRepository()->findByRelation($referencesForeignTable, $referencesFieldName, $referencesForeignUid), $fileObjects);
                                }
-                               $referencesForeignTable = $this->stdWrapValue('table', $conf['references.'], $table);
-                               $referencesForeignUid = $this->stdWrapValue('uid', $conf['references.'], isset($this->cObj->data['_LOCALIZED_UID']) ? $this->cObj->data['_LOCALIZED_UID'] : $this->cObj->data['uid']);
-                               $this->addToArray($fileRepository->findByRelation($referencesForeignTable, $referencesFieldName, $referencesForeignUid), $fileObjects);
                        }
                }
                if ($conf['files'] || $conf['files.']) {
@@ -89,10 +104,10 @@ class FilesContentObject extends \TYPO3\CMS\Frontend\ContentObject\AbstractConte
                        files = 12,14,15# using stdWrap:
                        files.field = some_field
                         */
-                       $fileUids = GeneralUtility::trimExplode(',', $this->stdWrapValue('files', $conf), TRUE);
+                       $fileUids = GeneralUtility::intExplode(',', $this->stdWrapValue('files', $conf), TRUE);
                        foreach ($fileUids as $fileUid) {
                                try {
-                                       $this->addToArray($fileRepository->findByUid($fileUid), $fileObjects);
+                                       $this->addToArray($this->getFileRepository()->findByUid($fileUid), $fileObjects);
                                } catch (\TYPO3\CMS\Core\Resource\Exception $e) {
                                        /** @var \TYPO3\CMS\Core\Log\Logger $logger */
                                        $logger = GeneralUtility::makeInstance('TYPO3\CMS\Core\Log\LogManager')->getLogger();
@@ -101,12 +116,10 @@ class FilesContentObject extends \TYPO3\CMS\Frontend\ContentObject\AbstractConte
                        }
                }
                if ($conf['collections'] || $conf['collections.']) {
-                       $collectionUids = GeneralUtility::trimExplode(',', $this->stdWrapValue('collections', $conf), TRUE);
-                       /** @var \TYPO3\CMS\Core\Resource\FileCollectionRepository $collectionRepository */
-                       $collectionRepository = GeneralUtility::makeInstance('TYPO3\\CMS\\Core\\Resource\\FileCollectionRepository');
+                       $collectionUids = GeneralUtility::intExplode(',', $this->stdWrapValue('collections', $conf), TRUE);
                        foreach ($collectionUids as $collectionUid) {
                                try {
-                                       $fileCollection = $collectionRepository->findByUid($collectionUid);
+                                       $fileCollection = $this->getCollectionRepository()->findByUid($collectionUid);
                                        if ($fileCollection instanceof \TYPO3\CMS\Core\Resource\Collection\AbstractFileCollection) {
                                                $fileCollection->loadContents();
                                                $this->addToArray($fileCollection->getItems(), $fileObjects);
@@ -120,12 +133,10 @@ class FilesContentObject extends \TYPO3\CMS\Frontend\ContentObject\AbstractConte
                }
                if ($conf['folders'] || $conf['folders.']) {
                        $folderIdentifiers = GeneralUtility::trimExplode(',', $this->stdWrapValue('folders', $conf));
-                       /** @var \TYPO3\CMS\Core\Resource\ResourceFactory $fileFactory */
-                       $fileFactory = GeneralUtility::makeInstance('TYPO3\\CMS\\Core\\Resource\\ResourceFactory');
                        foreach ($folderIdentifiers as $folderIdentifier) {
                                if ($folderIdentifier) {
                                        try {
-                                               $folder = $fileFactory->getFolderObjectFromCombinedIdentifier($folderIdentifier);
+                                               $folder = $this->getFileFactory()->getFolderObjectFromCombinedIdentifier($folderIdentifier);
                                                if ($folder instanceof \TYPO3\CMS\Core\Resource\Folder) {
                                                        $this->addToArray($folder->getFiles(), $fileObjects);
                                                }
@@ -148,7 +159,7 @@ class FilesContentObject extends \TYPO3\CMS\Frontend\ContentObject\AbstractConte
                        $sortingProperty = $this->stdWrapValue('sorting', $conf);
                }
                if ($sortingProperty !== '' && count($fileObjects) > 1) {
-                       usort($fileObjects, function(\TYPO3\CMS\Core\Resource\FileInterface $a, \TYPO3\CMS\Core\Resource\FileInterface $b) use($sortingProperty) {
+                       @usort($fileObjects, function(\TYPO3\CMS\Core\Resource\FileInterface $a, \TYPO3\CMS\Core\Resource\FileInterface $b) use($sortingProperty) {
                                if ($a->hasProperty($sortingProperty) && $b->hasProperty($sortingProperty)) {
                                        return strnatcasecmp($a->getProperty($sortingProperty), $b->getProperty($sortingProperty));
                                } else {
@@ -160,25 +171,25 @@ class FilesContentObject extends \TYPO3\CMS\Frontend\ContentObject\AbstractConte
                $availableFileObjectCount = count($fileObjects);
 
                $start = 0;
-               if (array_key_exists('begin', $conf)) {
+               if (!empty($conf['begin'])) {
                        $start = intval($conf['begin']);
                }
-               if (array_key_exists('begin.', $conf)) {
+               if (!empty($conf['begin.'])) {
                        $start = intval($this->cObj->stdWrap($start, $conf['begin.']));
                }
                $start = MathUtility::forceIntegerInRange($start, 0, $availableFileObjectCount);
 
                $limit = $availableFileObjectCount;
-               if (array_key_exists('maxItems', $conf)) {
+               if (!empty($conf['maxItems'])) {
                        $limit = intval($conf['maxItems']);
                }
-               if (array_key_exists('maxItems.', $conf)) {
+               if (!empty($conf['maxItems.'])) {
                        $limit = intval($this->cObj->stdWrap($limit, $conf['maxItems.']));
                }
 
-               $end = MathUtility::forceIntegerInRange($start + $limit, 0, $availableFileObjectCount);
+               $end = MathUtility::forceIntegerInRange($start + $limit, $start, $availableFileObjectCount);
 
-               $GLOBALS['TSFE']->register['FILES_COUNT'] = $limit < $availableFileObjectCount ? $limit : $availableFileObjectCount;
+               $GLOBALS['TSFE']->register['FILES_COUNT'] = min($limit, $availableFileObjectCount);
                $fileObjectCounter = 0;
                $keys = array_keys($fileObjects);
                for ($i = $start; $i < $end; $i++) {
@@ -194,11 +205,80 @@ class FilesContentObject extends \TYPO3\CMS\Frontend\ContentObject\AbstractConte
                return $content;
        }
 
+       /**
+        * Sets the file factory.
+        *
+        * @param \TYPO3\CMS\Core\Resource\ResourceFactory $fileFactory
+        * @return void
+        */
+       public function setFileFactory($fileFactory) {
+               $this->fileFactory = $fileFactory;
+       }
+
+       /**
+        * Returns the file factory.
+        *
+        * @return \TYPO3\CMS\Core\Resource\ResourceFactory
+        */
+       public function getFileFactory() {
+               if ($this->fileFactory === NULL) {
+                       $this->fileFactory = GeneralUtility::makeInstance('TYPO3\\CMS\\Core\\Resource\\ResourceFactory');
+               }
+
+               return $this->fileFactory;
+       }
+
+       /**
+        * Sets the file repository.
+        *
+        * @param \TYPO3\CMS\Core\Resource\FileRepository $fileRepository
+        * @return void
+        */
+       public function setFileRepository($fileRepository) {
+               $this->fileRepository = $fileRepository;
+       }
+
+       /**
+        * Returns the file repository.
+        *
+        * @return \TYPO3\CMS\Core\Resource\FileRepository
+        */
+       public function getFileRepository() {
+               if ($this->fileRepository === NULL) {
+                       $this->fileRepository = GeneralUtility::makeInstance('TYPO3\\CMS\\Core\\Resource\\FileRepository');
+               }
+
+               return $this->fileRepository;
+       }
+
+       /**
+        * Sets the collection repository.
+        *
+        * @param \TYPO3\CMS\Core\Resource\FileCollectionRepository $collectionRepository
+        * @return void
+        */
+       public function setCollectionRepository($collectionRepository) {
+               $this->collectionRepository = $collectionRepository;
+       }
+
+       /**
+        * Returns the collection repository.
+        *
+        * @return \TYPO3\CMS\Core\Resource\FileCollectionRepository
+        */
+       public function getCollectionRepository() {
+               if ($this->collectionRepository === NULL) {
+                       $this->collectionRepository = GeneralUtility::makeInstance('TYPO3\\CMS\\Core\\Resource\\FileCollectionRepository');
+               }
+
+               return $this->collectionRepository;
+       }
+
        /**
         * Adds $newItems to $theArray, which is passed by reference. Array must only consist of numerical keys.
         *
-        * @param mixed $newItems Array with new items or single object that's added.
-        * @param array $theArray The array the new items should be added to. Must only contain numeric keys (for array_merge() to add items instead of replacing).
+        * @param mixed $newItems Array with new items or single object that's added.
+        * @param array $theArray The array the new items should be added to. Must only contain numeric keys (for array_merge() to add items instead of replacing).
         */
        protected function addToArray($newItems, array &$theArray) {
                if (is_array($newItems)) {
diff --git a/typo3/sysext/frontend/Tests/Unit/ContentObject/FilesContentObjectTest.php b/typo3/sysext/frontend/Tests/Unit/ContentObject/FilesContentObjectTest.php
new file mode 100644 (file)
index 0000000..cab43f3
--- /dev/null
@@ -0,0 +1,846 @@
+<?php
+namespace TYPO3\CMS\Frontend\Tests\Unit\ContentObject;
+
+/***************************************************************
+ *  Copyright notice
+ *
+ *  (c) 2013 Nicole Cordes <typo3@cordes.co>
+ *  All rights reserved
+ *
+ *  This script is part of the TYPO3 project. The TYPO3 project is
+ *  free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  The GNU General Public License can be found at
+ *  http://www.gnu.org/copyleft/gpl.html.
+ *
+ *  This script is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  This copyright notice MUST APPEAR in all copies of the script!
+ ***************************************************************/
+/**
+ * Testcase for TYPO3\CMS\Frontend\ContentObject\FilesContentObject
+ *
+ * @author Nicole Cordes <typo3@cordes.co>
+ */
+class FilesContentObjectTest extends \TYPO3\CMS\Core\Tests\UnitTestCase {
+
+       /**
+        * @var \TYPO3\CMS\Frontend\ContentObject\FilesContentObject|\PHPUnit_Framework_MockObject_MockObject
+        */
+       protected $sut = NULL;
+
+       /**
+        * @var \TYPO3\CMS\Frontend\Controller\TypoScriptFrontendController
+        */
+       protected $tsfe = NULL;
+
+       /**
+        * Set up
+        */
+       public function setUp() {
+               $templateService = $this->getMock('TYPO3\\CMS\\Core\\TypoScript\\TemplateService', array('getFileName', 'linkData'));
+               $this->tsfe = $this->getMock('TYPO3\\CMS\\Frontend\\Controller\\TypoScriptFrontendController', array('dummy'), array(), '', FALSE);
+               $this->tsfe->tmpl = $templateService;
+               $this->tsfe->config = array();
+               $this->tsfe->page = array();
+               $sysPageMock = $this->getMock('TYPO3\\CMS\\Frontend\\Page\\PageRepository', array('getRawRecord'));
+               $this->tsfe->sys_page = $sysPageMock;
+               $GLOBALS['TSFE'] = $this->tsfe;
+               $GLOBALS['TSFE']->csConvObj = new \TYPO3\CMS\Core\Charset\CharsetConverter();
+               $GLOBALS['TSFE']->renderCharset = 'utf-8';
+
+               $contentObject = $this->getMock('TYPO3\\CMS\\Frontend\\ContentObject\\ContentObjectRenderer', array('dummy'));
+               $this->sut = $this->getMock('TYPO3\CMS\Frontend\ContentObject\FilesContentObject', array('dummy'), array($contentObject));
+       }
+
+       /**
+        * Tear down
+        */
+       public function tearDown() {
+               unset($this->sut, $this->tsfe);
+       }
+
+       /**
+        * @return array
+        */
+       public function renderReturnsFilesForFileReferencesDataProvider() {
+               return array(
+                       'One file reference' => array(
+                               array(
+                                       'references' => '1',
+                                       'renderObj' => 'TEXT',
+                                       'renderObj.' => array(
+                                               'data' => 'file:current:name',
+                                               'wrap' => '<p>|</p>',
+                                       ),
+                               ),
+                               '<p>File 1</p>',
+                       ),
+                       'One file reference with begin higher than allowed' => array(
+                               array(
+                                       'references' => '1',
+                                       'begin' => '1',
+                                       'renderObj' => 'TEXT',
+                                       'renderObj.' => array(
+                                               'data' => 'file:current:name',
+                                               'wrap' => '<p>|</p>',
+                                       ),
+                               ),
+                               '',
+                       ),
+                       'One file reference with maxItems higher than allowed' => array(
+                               array(
+                                       'references' => '1',
+                                       'maxItems' => '2',
+                                       'renderObj' => 'TEXT',
+                                       'renderObj.' => array(
+                                               'data' => 'file:current:name',
+                                               'wrap' => '<p>|</p>',
+                                       ),
+                               ),
+                               '<p>File 1</p>',
+                       ),
+                       'Multiple file references' => array(
+                               array(
+                                       'references' => '1,2,3',
+                                       'renderObj' => 'TEXT',
+                                       'renderObj.' => array(
+                                               'data' => 'file:current:name',
+                                               'wrap' => '<p>|</p>',
+                                       ),
+                               ),
+                               '<p>File 1</p><p>File 2</p><p>File 3</p>',
+                       ),
+                       'Multiple file references with begin' => array(
+                               array(
+                                       'references' => '1,2,3',
+                                       'begin' => '1',
+                                       'renderObj' => 'TEXT',
+                                       'renderObj.' => array(
+                                               'data' => 'file:current:name',
+                                               'wrap' => '<p>|</p>',
+                                       ),
+                               ),
+                               '<p>File 2</p><p>File 3</p>',
+                       ),
+                       'Multiple file references with negative begin' => array(
+                               array(
+                                       'references' => '1,2,3',
+                                       'begin' => '-1',
+                                       'renderObj' => 'TEXT',
+                                       'renderObj.' => array(
+                                               'data' => 'file:current:name',
+                                               'wrap' => '<p>|</p>',
+                                       ),
+                               ),
+                               '<p>File 1</p><p>File 2</p><p>File 3</p>',
+                       ),
+                       'Multiple file references with maxItems' => array(
+                               array(
+                                       'references' => '1,2,3',
+                                       'maxItems' => '2',
+                                       'renderObj' => 'TEXT',
+                                       'renderObj.' => array(
+                                               'data' => 'file:current:name',
+                                               'wrap' => '<p>|</p>',
+                                       ),
+                               ),
+                               '<p>File 1</p><p>File 2</p>',
+                       ),
+                       'Multiple file references with negative maxItems' => array(
+                               array(
+                                       'references' => '1,2,3',
+                                       'maxItems' => '-2',
+                                       'renderObj' => 'TEXT',
+                                       'renderObj.' => array(
+                                               'data' => 'file:current:name',
+                                               'wrap' => '<p>|</p>',
+                                       ),
+                               ),
+                               '',
+                       ),
+                       'Multiple file references with begin and maxItems' => array(
+                               array(
+                                       'references' => '1,2,3',
+                                       'begin' => '1',
+                                       'maxItems' => '1',
+                                       'renderObj' => 'TEXT',
+                                       'renderObj.' => array(
+                                               'data' => 'file:current:name',
+                                               'wrap' => '<p>|</p>',
+                                       ),
+                               ),
+                               '<p>File 2</p>',
+                       ),
+                       'Multiple file references unsorted' => array(
+                               array(
+                                       'references' => '1,3,2',
+                                       'renderObj' => 'TEXT',
+                                       'renderObj.' => array(
+                                               'data' => 'file:current:name',
+                                               'wrap' => '<p>|</p>',
+                                       ),
+                               ),
+                               '<p>File 1</p><p>File 3</p><p>File 2</p>',
+                       ),
+                       'Multiple file references sorted by name' => array(
+                               array(
+                                       'references' => '3,1,2',
+                                       'sorting' => 'name',
+                                       'renderObj' => 'TEXT',
+                                       'renderObj.' => array(
+                                               'data' => 'file:current:name',
+                                               'wrap' => '<p>|</p>',
+                                       ),
+                               ),
+                               '<p>File 1</p><p>File 2</p><p>File 3</p>',
+                       ),
+               );
+       }
+
+       /**
+        * @test
+        * @dataProvider renderReturnsFilesForFileReferencesDataProvider
+        */
+       public function renderReturnsFilesForFileReferences($configuration, $expected) {
+               $fileReferenceMap = array();
+               for ($i = 1; $i < 4; $i++) {
+                       $fileReference = $this->getMock('TYPO3\\CMS\\Core\\Resource\\FileReference', array(), array(), '', FALSE);
+                       $fileReference->expects($this->any())
+                               ->method('getName')
+                               ->will($this->returnValue('File ' . $i));
+                       $fileReference->expects($this->any())
+                               ->method('hasProperty')
+                               ->with('name')
+                               ->will($this->returnValue(TRUE));
+                       $fileReference->expects($this->any())
+                               ->method('getProperty')
+                               ->with('name')
+                               ->will($this->returnValue('File ' . $i));
+
+                       $fileReferenceMap[] = array($i, $fileReference);
+               }
+
+               $fileRepository = $this->getMock('TYPO3\\CMS\\Core\\Resource\\FileRepository');
+               $fileRepository->expects($this->any())
+                       ->method('findFileReferenceByUid')
+                       ->will($this->returnValueMap($fileReferenceMap));
+               $this->sut->setFileRepository($fileRepository);
+
+               $this->assertSame($expected, $this->sut->render($configuration));
+       }
+
+       /**
+        * @return array
+        */
+       public function renderReturnsFilesForFilesDataProvider() {
+               return array(
+                       'One file' => array(
+                               array(
+                                       'files' => '1',
+                                       'renderObj' => 'TEXT',
+                                       'renderObj.' => array(
+                                               'data' => 'file:current:name',
+                                               'wrap' => '<p>|</p>',
+                                       ),
+                               ),
+                               '<p>File 1</p>',
+                       ),
+                       'One file with begin higher than allowed' => array(
+                               array(
+                                       'files' => '1',
+                                       'begin' => '1',
+                                       'renderObj' => 'TEXT',
+                                       'renderObj.' => array(
+                                               'data' => 'file:current:name',
+                                               'wrap' => '<p>|</p>',
+                                       ),
+                               ),
+                               '',
+                       ),
+                       'One file with maxItems higher than allowed' => array(
+                               array(
+                                       'files' => '1',
+                                       'maxItems' => '2',
+                                       'renderObj' => 'TEXT',
+                                       'renderObj.' => array(
+                                               'data' => 'file:current:name',
+                                               'wrap' => '<p>|</p>',
+                                       ),
+                               ),
+                               '<p>File 1</p>',
+                       ),
+                       'Multiple files' => array(
+                               array(
+                                       'files' => '1,2,3',
+                                       'renderObj' => 'TEXT',
+                                       'renderObj.' => array(
+                                               'data' => 'file:current:name',
+                                               'wrap' => '<p>|</p>',
+                                       ),
+                               ),
+                               '<p>File 1</p><p>File 2</p><p>File 3</p>',
+                       ),
+                       'Multiple files with begin' => array(
+                               array(
+                                       'files' => '1,2,3',
+                                       'begin' => '1',
+                                       'renderObj' => 'TEXT',
+                                       'renderObj.' => array(
+                                               'data' => 'file:current:name',
+                                               'wrap' => '<p>|</p>',
+                                       ),
+                               ),
+                               '<p>File 2</p><p>File 3</p>',
+                       ),
+                       'Multiple files with negative begin' => array(
+                               array(
+                                       'files' => '1,2,3',
+                                       'begin' => '-1',
+                                       'renderObj' => 'TEXT',
+                                       'renderObj.' => array(
+                                               'data' => 'file:current:name',
+                                               'wrap' => '<p>|</p>',
+                                       ),
+                               ),
+                               '<p>File 1</p><p>File 2</p><p>File 3</p>',
+                       ),
+                       'Multiple files with maxItems' => array(
+                               array(
+                                       'files' => '1,2,3',
+                                       'maxItems' => '2',
+                                       'renderObj' => 'TEXT',
+                                       'renderObj.' => array(
+                                               'data' => 'file:current:name',
+                                               'wrap' => '<p>|</p>',
+                                       ),
+                               ),
+                               '<p>File 1</p><p>File 2</p>',
+                       ),
+                       'Multiple files with negative maxItems' => array(
+                               array(
+                                       'files' => '1,2,3',
+                                       'maxItems' => '-2',
+                                       'renderObj' => 'TEXT',
+                                       'renderObj.' => array(
+                                               'data' => 'file:current:name',
+                                               'wrap' => '<p>|</p>',
+                                       ),
+                               ),
+                               '',
+                       ),
+                       'Multiple files with begin and maxItems' => array(
+                               array(
+                                       'files' => '1,2,3',
+                                       'begin' => '1',
+                                       'maxItems' => '1',
+                                       'renderObj' => 'TEXT',
+                                       'renderObj.' => array(
+                                               'data' => 'file:current:name',
+                                               'wrap' => '<p>|</p>',
+                                       ),
+                               ),
+                               '<p>File 2</p>',
+                       ),
+                       'Multiple files unsorted' => array(
+                               array(
+                                       'files' => '1,3,2',
+                                       'renderObj' => 'TEXT',
+                                       'renderObj.' => array(
+                                               'data' => 'file:current:name',
+                                               'wrap' => '<p>|</p>',
+                                       ),
+                               ),
+                               '<p>File 1</p><p>File 3</p><p>File 2</p>',
+                       ),
+                       'Multiple files sorted by name' => array(
+                               array(
+                                       'files' => '3,1,2',
+                                       'sorting' => 'name',
+                                       'renderObj' => 'TEXT',
+                                       'renderObj.' => array(
+                                               'data' => 'file:current:name',
+                                               'wrap' => '<p>|</p>',
+                                       ),
+                               ),
+                               '<p>File 1</p><p>File 2</p><p>File 3</p>',
+                       ),
+               );
+       }
+
+       /**
+        * @test
+        * @dataProvider renderReturnsFilesForFilesDataProvider
+        */
+       public function renderReturnsFilesForFiles($configuration, $expected) {
+               $fileMap = array();
+               for ($i = 1; $i < 4; $i++) {
+                       $file = $this->getMock('TYPO3\\CMS\\Core\\Resource\\File', array(), array(), '', FALSE);
+                       $file->expects($this->any())
+                               ->method('getName')
+                               ->will($this->returnValue('File ' . $i));
+                       $file->expects($this->any())
+                               ->method('hasProperty')
+                               ->with('name')
+                               ->will($this->returnValue(TRUE));
+                       $file->expects($this->any())
+                               ->method('getProperty')
+                               ->with('name')
+                               ->will($this->returnValue('File ' . $i));
+
+                       $fileMap[] = array($i, $file);
+               }
+
+               $fileRepository = $this->getMock('TYPO3\\CMS\\Core\\Resource\\FileRepository');
+               $fileRepository->expects($this->any())
+                       ->method('findByUid')
+                       ->will($this->returnValueMap($fileMap));
+               $this->sut->setFileRepository($fileRepository);
+
+               $this->assertSame($expected, $this->sut->render($configuration));
+       }
+
+       /**
+        * @return array
+        */
+       public function renderReturnsFilesForCollectionsDataProvider() {
+               return array(
+                       'One collection' => array(
+                               array(
+                                       'collections' => '1',
+                                       'renderObj' => 'TEXT',
+                                       'renderObj.' => array(
+                                               'data' => 'file:current:name',
+                                               'wrap' => '<p>|</p>',
+                                       ),
+                               ),
+                               '<p>File 1</p><p>File 2</p><p>File 3</p>',
+                       ),
+                       'One collection with begin' => array(
+                               array(
+                                       'collections' => '1',
+                                       'begin' => '1',
+                                       'renderObj' => 'TEXT',
+                                       'renderObj.' => array(
+                                               'data' => 'file:current:name',
+                                               'wrap' => '<p>|</p>',
+                                       ),
+                               ),
+                               '<p>File 2</p><p>File 3</p>',
+                       ),
+                       'One collection with begin higher than allowed' => array(
+                               array(
+                                       'collections' => '1',
+                                       'begin' => '3',
+                                       'renderObj' => 'TEXT',
+                                       'renderObj.' => array(
+                                               'data' => 'file:current:name',
+                                               'wrap' => '<p>|</p>',
+                                       ),
+                               ),
+                               '',
+                       ),
+                       'One collection with maxItems' => array(
+                               array(
+                                       'collections' => '1',
+                                       'maxItems' => '2',
+                                       'renderObj' => 'TEXT',
+                                       'renderObj.' => array(
+                                               'data' => 'file:current:name',
+                                               'wrap' => '<p>|</p>',
+                                       ),
+                               ),
+                               '<p>File 1</p><p>File 2</p>',
+                       ),
+                       'One collection with maxItems higher than allowed' => array(
+                               array(
+                                       'collections' => '1',
+                                       'maxItems' => '4',
+                                       'renderObj' => 'TEXT',
+                                       'renderObj.' => array(
+                                               'data' => 'file:current:name',
+                                               'wrap' => '<p>|</p>',
+                                       ),
+                               ),
+                               '<p>File 1</p><p>File 2</p><p>File 3</p>',
+                       ),
+                       'One collections with begin and maxItems' => array(
+                               array(
+                                       'collections' => '1',
+                                       'begin' => '1',
+                                       'maxItems' => '1',
+                                       'renderObj' => 'TEXT',
+                                       'renderObj.' => array(
+                                               'data' => 'file:current:name',
+                                               'wrap' => '<p>|</p>',
+                                       ),
+                               ),
+                               '<p>File 2</p>',
+                       ),
+                       'Multiple collections' => array(
+                               array(
+                                       'collections' => '1,2,3',
+                                       'renderObj' => 'TEXT',
+                                       'renderObj.' => array(
+                                               'data' => 'file:current:name',
+                                               'wrap' => '<p>|</p>',
+                                       ),
+                               ),
+                               '<p>File 1</p><p>File 2</p><p>File 3</p><p>File 4</p><p>File 5</p><p>File 6</p><p>File 7</p><p>File 8</p><p>File 9</p>',
+                       ),
+                       'Multiple collections with begin' => array(
+                               array(
+                                       'collections' => '1,2,3',
+                                       'begin' => '3',
+                                       'renderObj' => 'TEXT',
+                                       'renderObj.' => array(
+                                               'data' => 'file:current:name',
+                                               'wrap' => '<p>|</p>',
+                                       ),
+                               ),
+                               '<p>File 4</p><p>File 5</p><p>File 6</p><p>File 7</p><p>File 8</p><p>File 9</p>',
+                       ),
+                       'Multiple collections with negative begin' => array(
+                               array(
+                                       'collections' => '1,2,3',
+                                       'begin' => '-3',
+                                       'renderObj' => 'TEXT',
+                                       'renderObj.' => array(
+                                               'data' => 'file:current:name',
+                                               'wrap' => '<p>|</p>',
+                                       ),
+                               ),
+                               '<p>File 1</p><p>File 2</p><p>File 3</p><p>File 4</p><p>File 5</p><p>File 6</p><p>File 7</p><p>File 8</p><p>File 9</p>',
+                       ),
+                       'Multiple collections with maxItems' => array(
+                               array(
+                                       'collections' => '1,2,3',
+                                       'maxItems' => '5',
+                                       'renderObj' => 'TEXT',
+                                       'renderObj.' => array(
+                                               'data' => 'file:current:name',
+                                               'wrap' => '<p>|</p>',
+                                       ),
+                               ),
+                               '<p>File 1</p><p>File 2</p><p>File 3</p><p>File 4</p><p>File 5</p>',
+                       ),
+                       'Multiple collections with negative maxItems' => array(
+                               array(
+                                       'collections' => '1,2,3',
+                                       'maxItems' => '-5',
+                                       'renderObj' => 'TEXT',
+                                       'renderObj.' => array(
+                                               'data' => 'file:current:name',
+                                               'wrap' => '<p>|</p>',
+                                       ),
+                               ),
+                               '',
+                       ),
+                       'Multiple collections with begin and maxItems' => array(
+                               array(
+                                       'collections' => '1,2,3',
+                                       'begin' => '4',
+                                       'maxItems' => '3',
+                                       'renderObj' => 'TEXT',
+                                       'renderObj.' => array(
+                                               'data' => 'file:current:name',
+                                               'wrap' => '<p>|</p>',
+                                       ),
+                               ),
+                               '<p>File 5</p><p>File 6</p><p>File 7</p>',
+                       ),
+                       'Multiple collections unsorted' => array(
+                               array(
+                                       'collections' => '1,3,2',
+                                       'renderObj' => 'TEXT',
+                                       'renderObj.' => array(
+                                               'data' => 'file:current:name',
+                                               'wrap' => '<p>|</p>',
+                                       ),
+                               ),
+                               '<p>File 1</p><p>File 2</p><p>File 3</p><p>File 7</p><p>File 8</p><p>File 9</p><p>File 4</p><p>File 5</p><p>File 6</p>',
+                       ),
+                       'Multiple collections sorted by name' => array(
+                               array(
+                                       'collections' => '3,1,2',
+                                       'sorting' => 'name',
+                                       'renderObj' => 'TEXT',
+                                       'renderObj.' => array(
+                                               'data' => 'file:current:name',
+                                               'wrap' => '<p>|</p>',
+                                       ),
+                               ),
+                               '<p>File 1</p><p>File 2</p><p>File 3</p><p>File 4</p><p>File 5</p><p>File 6</p><p>File 7</p><p>File 8</p><p>File 9</p>',
+                       ),
+               );
+       }
+
+       /**
+        * @test
+        * @dataProvider renderReturnsFilesForCollectionsDataProvider
+        */
+       public function renderReturnsFilesForCollections($configuration, $expected) {
+               $collectionMap = array();
+               $fileCount = 1;
+               for ($i = 1; $i < 4; $i++) {
+                       $fileReferenceArray = array();
+                       for ($j = 1; $j < 4; $j++) {
+                               $fileReference = $this->getMock('TYPO3\\CMS\\Core\\Resource\\FileReference', array(), array(), '', FALSE);
+                               $fileReference->expects($this->any())
+                                       ->method('getName')
+                                       ->will($this->returnValue('File ' . $fileCount));
+                               $fileReference->expects($this->any())
+                                       ->method('hasProperty')
+                                       ->with('name')
+                                       ->will($this->returnValue(TRUE));
+                               $fileReference->expects($this->any())
+                                       ->method('getProperty')
+                                       ->with('name')
+                                       ->will($this->returnValue('File ' . $fileCount));
+
+                               $fileReferenceArray[] = $fileReference;
+                               $fileCount++;
+                       }
+
+                       $collection = $this->getMock('TYPO3\\CMS\\Core\\Resource\\Collection\\StaticFileCollection', array(), array(), '', FALSE);
+                       $collection->expects($this->any())
+                               ->method('getItems')
+                               ->will($this->returnValue($fileReferenceArray));
+
+                       $collectionMap[] = array($i, $collection);
+               }
+
+               $collectionRepository = $this->getMock('TYPO3\\CMS\\Core\\Resource\\FileCollectionRepository');
+               $collectionRepository->expects($this->any())
+                       ->method('findByUid')
+                       ->will($this->returnValueMap($collectionMap));
+               $this->sut->setCollectionRepository($collectionRepository);
+
+               $this->assertSame($expected, $this->sut->render($configuration));
+       }
+
+       /**
+        * @return array
+        */
+       public function renderReturnsFilesForFoldersDataProvider() {
+               return array(
+                       'One folder' => array(
+                               array(
+                                       'folders' => '1:myfolder/',
+                                       'renderObj' => 'TEXT',
+                                       'renderObj.' => array(
+                                               'data' => 'file:current:name',
+                                               'wrap' => '<p>|</p>',
+                                       ),
+                               ),
+                               '<p>File 1</p><p>File 2</p><p>File 3</p>',
+                       ),
+                       'One folder with begin' => array(
+                               array(
+                                       'folders' => '1:myfolder/',
+                                       'begin' => '1',
+                                       'renderObj' => 'TEXT',
+                                       'renderObj.' => array(
+                                               'data' => 'file:current:name',
+                                               'wrap' => '<p>|</p>',
+                                       ),
+                               ),
+                               '<p>File 2</p><p>File 3</p>',
+                       ),
+                       'One folder with begin higher than allowed' => array(
+                               array(
+                                       'folders' => '1:myfolder/',
+                                       'begin' => '3',
+                                       'renderObj' => 'TEXT',
+                                       'renderObj.' => array(
+                                               'data' => 'file:current:name',
+                                               'wrap' => '<p>|</p>',
+                                       ),
+                               ),
+                               '',
+                       ),
+                       'One folder with maxItems' => array(
+                               array(
+                                       'folders' => '1:myfolder/',
+                                       'maxItems' => '2',
+                                       'renderObj' => 'TEXT',
+                                       'renderObj.' => array(
+                                               'data' => 'file:current:name',
+                                               'wrap' => '<p>|</p>',
+                                       ),
+                               ),
+                               '<p>File 1</p><p>File 2</p>',
+                       ),
+                       'One folder with maxItems higher than allowed' => array(
+                               array(
+                                       'folders' => '1:myfolder/',
+                                       'maxItems' => '4',
+                                       'renderObj' => 'TEXT',
+                                       'renderObj.' => array(
+                                               'data' => 'file:current:name',
+                                               'wrap' => '<p>|</p>',
+                                       ),
+                               ),
+                               '<p>File 1</p><p>File 2</p><p>File 3</p>',
+                       ),
+                       'One folder with begin and maxItems' => array(
+                               array(
+                                       'folders' => '1:myfolder/',
+                                       'begin' => '1',
+                                       'maxItems' => '1',
+                                       'renderObj' => 'TEXT',
+                                       'renderObj.' => array(
+                                               'data' => 'file:current:name',
+                                               'wrap' => '<p>|</p>',
+                                       ),
+                               ),
+                               '<p>File 2</p>',
+                       ),
+                       'Multiple folders' => array(
+                               array(
+                                       'folders' => '1:myfolder/,2:myfolder/,3:myfolder/',
+                                       'renderObj' => 'TEXT',
+                                       'renderObj.' => array(
+                                               'data' => 'file:current:name',
+                                               'wrap' => '<p>|</p>',
+                                       ),
+                               ),
+                               '<p>File 1</p><p>File 2</p><p>File 3</p><p>File 4</p><p>File 5</p><p>File 6</p><p>File 7</p><p>File 8</p><p>File 9</p>',
+                       ),
+                       'Multiple folders with begin' => array(
+                               array(
+                                       'folders' => '1:myfolder/,2:myfolder/,3:myfolder/',
+                                       'begin' => '3',
+                                       'renderObj' => 'TEXT',
+                                       'renderObj.' => array(
+                                               'data' => 'file:current:name',
+                                               'wrap' => '<p>|</p>',
+                                       ),
+                               ),
+                               '<p>File 4</p><p>File 5</p><p>File 6</p><p>File 7</p><p>File 8</p><p>File 9</p>',
+                       ),
+                       'Multiple folders with negative begin' => array(
+                               array(
+                                       'folders' => '1:myfolder/,2:myfolder/,3:myfolder/',
+                                       'begin' => '-3',
+                                       'renderObj' => 'TEXT',
+                                       'renderObj.' => array(
+                                               'data' => 'file:current:name',
+                                               'wrap' => '<p>|</p>',
+                                       ),
+                               ),
+                               '<p>File 1</p><p>File 2</p><p>File 3</p><p>File 4</p><p>File 5</p><p>File 6</p><p>File 7</p><p>File 8</p><p>File 9</p>',
+                       ),
+                       'Multiple folders with maxItems' => array(
+                               array(
+                                       'folders' => '1:myfolder/,2:myfolder/,3:myfolder/',
+                                       'maxItems' => '5',
+                                       'renderObj' => 'TEXT',
+                                       'renderObj.' => array(
+                                               'data' => 'file:current:name',
+                                               'wrap' => '<p>|</p>',
+                                       ),
+                               ),
+                               '<p>File 1</p><p>File 2</p><p>File 3</p><p>File 4</p><p>File 5</p>',
+                       ),
+                       'Multiple folders with negative maxItems' => array(
+                               array(
+                                       'folders' => '1:myfolder/,2:myfolder/,3:myfolder/',
+                                       'maxItems' => '-5',
+                                       'renderObj' => 'TEXT',
+                                       'renderObj.' => array(
+                                               'data' => 'file:current:name',
+                                               'wrap' => '<p>|</p>',
+                                       ),
+                               ),
+                               '',
+                       ),
+                       'Multiple folders with begin and maxItems' => array(
+                               array(
+                                       'folders' => '1:myfolder/,2:myfolder/,3:myfolder/',
+                                       'begin' => '4',
+                                       'maxItems' => '3',
+                                       'renderObj' => 'TEXT',
+                                       'renderObj.' => array(
+                                               'data' => 'file:current:name',
+                                               'wrap' => '<p>|</p>',
+                                       ),
+                               ),
+                               '<p>File 5</p><p>File 6</p><p>File 7</p>',
+                       ),
+                       'Multiple folders unsorted' => array(
+                               array(
+                                       'folders' => '1:myfolder/,3:myfolder/,2:myfolder/',
+                                       'renderObj' => 'TEXT',
+                                       'renderObj.' => array(
+                                               'data' => 'file:current:name',
+                                               'wrap' => '<p>|</p>',
+                                       ),
+                               ),
+                               '<p>File 1</p><p>File 2</p><p>File 3</p><p>File 7</p><p>File 8</p><p>File 9</p><p>File 4</p><p>File 5</p><p>File 6</p>',
+                       ),
+                       'Multiple folders sorted by name' => array(
+                               array(
+                                       'folders' => '3:myfolder/,1:myfolder/,2:myfolder/',
+                                       'sorting' => 'name',
+                                       'renderObj' => 'TEXT',
+                                       'renderObj.' => array(
+                                               'data' => 'file:current:name',
+                                               'wrap' => '<p>|</p>',
+                                       ),
+                               ),
+                               '<p>File 1</p><p>File 2</p><p>File 3</p><p>File 4</p><p>File 5</p><p>File 6</p><p>File 7</p><p>File 8</p><p>File 9</p>',
+                       ),
+               );
+       }
+
+       /**
+        * @test
+        * @dataProvider renderReturnsFilesForFoldersDataProvider
+        */
+       public function renderReturnsFilesForFolders($configuration, $expected) {
+               $folderMap = array();
+               $fileCount = 1;
+               for ($i = 1; $i < 4; $i++) {
+                       $fileArray = array();
+                       for ($j = 1; $j < 4; $j++) {
+                               $file = $this->getMock('TYPO3\\CMS\\Core\\Resource\\File', array(), array(), '', FALSE);
+                               $file->expects($this->any())
+                                       ->method('getName')
+                                       ->will($this->returnValue('File ' . $fileCount));
+                               $file->expects($this->any())
+                                       ->method('hasProperty')
+                                       ->with('name')
+                                       ->will($this->returnValue(TRUE));
+                               $file->expects($this->any())
+                                       ->method('getProperty')
+                                       ->with('name')
+                                       ->will($this->returnValue('File ' . $fileCount));
+
+                               $fileArray[] = $file;
+                               $fileCount++;
+                       }
+
+                       $folder = $this->getMock('TYPO3\\CMS\\Core\\Resource\\Folder', array(), array(), '', FALSE);
+                       $folder->expects($this->any())
+                               ->method('getFiles')
+                               ->will($this->returnValue($fileArray));
+
+                       $folderMap[] = array($i . ':myfolder/', $folder);
+               }
+
+               $fileFactory = $this->getMock('TYPO3\\CMS\\Core\\Resource\\ResourceFactory');
+               $fileFactory->expects($this->any())
+                       ->method('getFolderObjectFromCombinedIdentifier')
+                       ->will($this->returnValueMap($folderMap));
+               $this->sut->setFileFactory($fileFactory);
+
+               $this->assertSame($expected, $this->sut->render($configuration));
+       }
+}