diff --git a/typo3/sysext/extensionmanager/Classes/Domain/Repository/ExtensionRepository.php b/typo3/sysext/extensionmanager/Classes/Domain/Repository/ExtensionRepository.php index a1ca1374e1cdca251fa63049e67ba4169aebcf1b..c14376f08bb1f0139fda9fe0f9af81ade3b6b8ba 100644 --- a/typo3/sysext/extensionmanager/Classes/Domain/Repository/ExtensionRepository.php +++ b/typo3/sysext/extensionmanager/Classes/Domain/Repository/ExtensionRepository.php @@ -109,10 +109,11 @@ class ExtensionRepository extends \TYPO3\CMS\Extbase\Persistence\Repository { */ public function findOneByExtensionKeyAndVersion($extensionKey, $version) { $query = $this->createQuery(); + // Hint: This method must not filter out insecure extensions, if needed, + // it should be done on a different level, or with a helper method. $query->matching($query->logicalAnd( $query->equals('extensionKey', $extensionKey), - $query->equals('version', $version), - $query->greaterThanOrEqual('reviewState', 0) + $query->equals('version', $version) )); return $query->setLimit(1)->execute()->getFirst(); } diff --git a/typo3/sysext/extensionmanager/Classes/Domain/Repository/RepositoryRepository.php b/typo3/sysext/extensionmanager/Classes/Domain/Repository/RepositoryRepository.php index 945ea890c3c07fca378ee2a05353c00f24ef9175..b9eefad1b4e01b7bdb6977f60435a6717a33dfa6 100644 --- a/typo3/sysext/extensionmanager/Classes/Domain/Repository/RepositoryRepository.php +++ b/typo3/sysext/extensionmanager/Classes/Domain/Repository/RepositoryRepository.php @@ -58,7 +58,22 @@ class RepositoryRepository extends \TYPO3\CMS\Extbase\Persistence\Repository { )); } + /** + * Find main typo3.org repository + * + * @return \TYPO3\CMS\Extensionmanager\Domain\Model\Repository + */ + public function findOneTypo3OrgRepository() { + $allRepositories = $this->findAll(); + $typo3OrgRepository = NULL; + foreach ($allRepositories as $repository) { + /** @var $repository \TYPO3\CMS\Extensionmanager\Domain\Model\Repository */ + if ($repository->getTitle() === 'TYPO3.org Main Repository') { + $typo3OrgRepository = $repository; + break; + } + } + return $typo3OrgRepository; + } } - - ?> \ No newline at end of file diff --git a/typo3/sysext/extensionmanager/Classes/Report/ExtensionStatus.php b/typo3/sysext/extensionmanager/Classes/Report/ExtensionStatus.php new file mode 100644 index 0000000000000000000000000000000000000000..33af3f879bf47fc93d81af4110b222a262c1bfd7 --- /dev/null +++ b/typo3/sysext/extensionmanager/Classes/Report/ExtensionStatus.php @@ -0,0 +1,230 @@ +<?php +namespace TYPO3\CMS\Extensionmanager\Report; + +/*************************************************************** + * Copyright notice + * + * (c) 2010-2012 Steffen Kamper <steffen@typo3.org> + * 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. + * A copy is found in the textfile GPL.txt and important notices to the license + * from the author is found in LICENSE.txt distributed with these scripts. + * + * + * 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! + ***************************************************************/ + +/** + * Extension status reports + * + * @author Christian Kuhn <lolli@schwarzbu.ch> + */ +class ExtensionStatus implements \TYPO3\CMS\Reports\StatusProviderInterface { + + /** + * @var string + */ + protected $ok = ''; + + /** + * @var string + */ + protected $upToDate = ''; + + /** + * @var string + */ + protected $error = ''; + + /** + * @var \TYPO3\CMS\Extbase\Object\ObjectManager + */ + protected $objectManager = NULL; + + /** + * @var \TYPO3\CMS\Extensionmanager\Domain\Repository\RepositoryRepository + */ + protected $repositoryRepository = NULL; + + /** + * @var \TYPO3\CMS\Extensionmanager\Utility\ListUtility + */ + protected $listUtility = NULL; + + /** + * Default constructor + */ + public function __construct() { + $this->objectManager = \TYPO3\CMS\Core\Utility\GeneralUtility::makeInstance('TYPO3\\CMS\\Extbase\\Object\\ObjectManager'); + $this->repositoryRepository = $this->objectManager->get('TYPO3\\CMS\\Extensionmanager\\Domain\\Repository\\RepositoryRepository'); + $this->listUtility = $this->objectManager->get('TYPO3\\CMS\\Extensionmanager\\Utility\\ListUtility'); + } + + /** + * Determines extension manager status + * + * @return array List of statuses + */ + public function getStatus() { + $status = array(); + $status['mainRepositoryStatus'] = $this->getMainRepositoryStatus(); + + $extensionStatus = $this->getSecurityStatusOfExtensions(); + $status['extensionsSecurityStatusInstalled'] = $extensionStatus->loaded; + $status['extensionsSecurityStatusNotInstalled'] = $extensionStatus->existing; + + return $status; + } + + /** + * Check main repository status: existance, has extensions, last update younger than 7 days + * + * @return \TYPO3\CMS\Reports\Report\Status\Status + */ + protected function getMainRepositoryStatus() { + /** @var $mainRepository \TYPO3\CMS\Extensionmanager\Domain\Model\Repository */ + $mainRepository = $this->repositoryRepository->findOneTypo3OrgRepository(); + + if (is_null($mainRepository) === TRUE) { + $value = $GLOBALS['LANG']->sL('LLL:EXT:extensionmanager/Resources/Private/Language/locallang.xlf:report.status.mainRepository.notFound.value'); + $message = $GLOBALS['LANG']->sL('LLL:EXT:extensionmanager/Resources/Private/Language/locallang.xlf:report.status.mainRepository.notFound.message'); + $severity = \TYPO3\CMS\Reports\Status::ERROR; + } elseif ($mainRepository->getLastUpdate()->getTimestamp() < $GLOBALS['EXEC_TIME'] - 24 * 60 * 60 * 7) { + $value = $GLOBALS['LANG']->sL('LLL:EXT:extensionmanager/Resources/Private/Language/locallang.xlf:report.status.mainRepository.notUpToDate.value'); + $message = $GLOBALS['LANG']->sL('LLL:EXT:extensionmanager/Resources/Private/Language/locallang.xlf:report.status.mainRepository.notUpToDate.message'); + $severity = \TYPO3\CMS\Reports\Status::NOTICE; + } else { + $value = $GLOBALS['LANG']->sL('LLL:EXT:extensionmanager/Resources/Private/Language/locallang.xlf:report.status.mainRepository.upToDate.value'); + $message = ''; + $severity = \TYPO3\CMS\Reports\Status::OK; + } + + /** @var $status \TYPO3\CMS\Reports\Status */ + $status = $this->objectManager->get( + 'TYPO3\\CMS\\Reports\\Status', + $GLOBALS['LANG']->sL('LLL:EXT:extensionmanager/Resources/Private/Language/locallang.xlf:report.status.mainRepository.title'), + $value, + $message, + $severity + ); + + return $status; + } + + /** + * Get security status of loaded and installed extensions + * + * @return \stdClass with properties 'loaded' and 'existing' containing a TYPO3\CMS\Reports\Report\Status\Status object + */ + protected function getSecurityStatusOfExtensions() { + $extensionInformation = $this->listUtility->getAvailableAndInstalledExtensionsWithAdditionalInformation(); + $loadedInsecure = array(); + $existingInsecure = array(); + foreach ($extensionInformation as $extensionKey => $information) { + if ( + array_key_exists('terObject', $information) + && $information['terObject'] instanceof \TYPO3\CMS\Extensionmanager\Domain\Model\Extension + ) { + /** @var $terObject \TYPO3\CMS\Extensionmanager\Domain\Model\Extension */ + $terObject = $information['terObject']; + $insecureStatus = $terObject->getReviewState(); + if ($insecureStatus === -1) { + if ( + array_key_exists('installed', $information) + && $information['installed'] === TRUE + ) { + $loadedInsecure[] = array( + 'extensionKey' => $extensionKey, + 'version' => $terObject->getVersion(), + ); + } else { + $existingInsecure[] = array( + 'extensionKey' => $extensionKey, + 'version' => $terObject->getVersion(), + ); + } + } + } + } + + $result = new \stdClass(); + + if (count($loadedInsecure) === 0) { + $value = $GLOBALS['LANG']->sL('LLL:EXT:extensionmanager/Resources/Private/Language/locallang.xlf:report.status.loadedExtensions.noInsecureExtensionLoaded.value'); + $message = ''; + $severity = \TYPO3\CMS\Reports\Status::OK; + } else { + $value = sprintf( + $GLOBALS['LANG']->sL('LLL:EXT:extensionmanager/Resources/Private/Language/locallang.xlf:report.status.loadedExtensions.insecureExtensionLoaded.value'), + count($loadedInsecure) + ); + $extensionList = array(); + foreach ($loadedInsecure as $insecureExtension) { + $extensionList[] = sprintf( + $GLOBALS['LANG']->sL('LLL:EXT:extensionmanager/Resources/Private/Language/locallang.xlf:report.status.loadedExtensions.insecureExtensionLoaded.message.extension'), + $insecureExtension['extensionKey'], + $insecureExtension['version'] + ); + } + $message = sprintf( + $GLOBALS['LANG']->sL('LLL:EXT:extensionmanager/Resources/Private/Language/locallang.xlf:report.status.loadedExtensions.insecureExtensionLoaded.message'), + implode('', $extensionList) + ); + $severity = \TYPO3\CMS\Reports\Status::ERROR; + } + $result->loaded = $this->objectManager->get( + 'TYPO3\\CMS\\Reports\\Status', + $GLOBALS['LANG']->sL('LLL:EXT:extensionmanager/Resources/Private/Language/locallang.xlf:report.status.loadedExtensions.title'), + $value, + $message, + $severity + ); + + if (count($existingInsecure) === 0) { + $value = $GLOBALS['LANG']->sL('LLL:EXT:extensionmanager/Resources/Private/Language/locallang.xlf:report.status.existingExtensions.noInsecureExtensionExists.value'); + $message = ''; + $severity = \TYPO3\CMS\Reports\Status::OK; + } else { + $value = sprintf( + $GLOBALS['LANG']->sL('LLL:EXT:extensionmanager/Resources/Private/Language/locallang.xlf:report.status.existingExtensions.insecureExtensionExists.value'), + count($existingInsecure) + ); + $extensionList = array(); + foreach ($existingInsecure as $insecureExtension) { + $extensionList[] = sprintf( + $GLOBALS['LANG']->sL('LLL:EXT:extensionmanager/Resources/Private/Language/locallang.xlf:report.status.existingExtensions.insecureExtensionExists.message.extension'), + $insecureExtension['extensionKey'], + $insecureExtension['version'] + ); + } + $message = sprintf( + $GLOBALS['LANG']->sL('LLL:EXT:extensionmanager/Resources/Private/Language/locallang.xlf:report.status.existingExtensions.insecureExtensionExists.message'), + implode('', $extensionList) + ); + $severity = \TYPO3\CMS\Reports\Status::WARNING; + } + $result->existing = $this->objectManager->get( + 'TYPO3\\CMS\\Reports\\Status', + $GLOBALS['LANG']->sL('LLL:EXT:extensionmanager/Resources/Private/Language/locallang.xlf:report.status.existingExtensions.title'), + $value, + $message, + $severity + ); + + return $result; + } +} +?> \ No newline at end of file diff --git a/typo3/sysext/extensionmanager/Classes/Utility/ListUtility.php b/typo3/sysext/extensionmanager/Classes/Utility/ListUtility.php index 72b5f35ee95ada4a81bd4aab83dc0746a460c832..f62dd89d50ac035748f61298de3df168d51363b6 100644 --- a/typo3/sysext/extensionmanager/Classes/Utility/ListUtility.php +++ b/typo3/sysext/extensionmanager/Classes/Utility/ListUtility.php @@ -29,6 +29,11 @@ namespace TYPO3\CMS\Extensionmanager\Utility; /** * Utility for dealing with extension list related functions * + * @TODO: Refactor this API class: + * - The methods depend on each other, they take each others result, that could be done internally + * - There is no good wording to distinguish existing and loaded extensions + * - The name 'listUtility' is not good, the methods could be moved to some 'extensionInformationUtility', or a repository? + * * @author Susanne Moog <typo3@susannemoog.de> * @package Extension Manager * @subpackage Utility @@ -92,7 +97,7 @@ class ListUtility implements \TYPO3\CMS\Core\SingletonInterface { } /** - * Returns the list of available (installed) extensions + * Returns the list of available, but not necessarily loaded extensions * * @return array Array with two sub-arrays, list array (all extensions with info) and category index * @see getInstExtList() @@ -123,7 +128,7 @@ class ListUtility implements \TYPO3\CMS\Core\SingletonInterface { } /** - * Reduce the available extensions list to only loaded extensions + * Enrich the output of getAvailableExtensions() with an array key installed = 1 if an extension is loaded. * * @param array $availableExtensions * @return array diff --git a/typo3/sysext/extensionmanager/Resources/Private/Language/locallang.xlf b/typo3/sysext/extensionmanager/Resources/Private/Language/locallang.xlf index 14692732e700bc2f6796bdfc0e9f94ffb83506d1..3d27bf88ccbd338ce1d7032a2ae37f307a067e6c 100644 --- a/typo3/sysext/extensionmanager/Resources/Private/Language/locallang.xlf +++ b/typo3/sysext/extensionmanager/Resources/Private/Language/locallang.xlf @@ -229,12 +229,61 @@ <trans-unit id="extensionList.updateFromTer.label" xml:space="preserve"> <source>Retrieving Extension-List from TYPO3 Extension Repository (TER)</source> </trans-unit> + <trans-unit id="task.updateExtensionListTask.name" xml:space="preserve"> <source>Update extension list</source> </trans-unit> <trans-unit id="task.updateExtensionListTask.description" xml:space="preserve"> <source>Update TER extension list on a regular basis. Once a day is a good interval.</source> </trans-unit> + <trans-unit id="report.status.mainRepository.title" xml:space="preserve"> + <source>Update status of typo3.org main repository extension list</source> + </trans-unit> + <trans-unit id="report.status.mainRepository.notFound.value" xml:space="preserve"> + <source>Error</source> + </trans-unit> + <trans-unit id="report.status.mainRepository.notFound.message" xml:space="preserve"> + <source>The typo3.org extension repository was not found. Please import the main typo3.org extension repository in the install tool wizard.</source> + </trans-unit> + <trans-unit id="report.status.mainRepository.notUpToDate.value" xml:space="preserve"> + <source>Extension list is not up to date!</source> + </trans-unit> + <trans-unit id="report.status.mainRepository.notUpToDate.message" xml:space="preserve"> + <source>The Main Repository extension list is older than 7 days. Please update it in the Extension manager or Scheduler.</source> + </trans-unit> + <trans-unit id="report.status.mainRepository.upToDate.value" xml:space="preserve"> + <source>OK</source> + </trans-unit> + <trans-unit id="report.status.loadedExtensions.title" xml:space="preserve"> + <source>Security status of loaded extensions</source> + </trans-unit> + <trans-unit id="report.status.loadedExtensions.noInsecureExtensionLoaded.value" xml:space="preserve"> + <source>OK</source> + </trans-unit> + <trans-unit id="report.status.loadedExtensions.insecureExtensionLoaded.value" xml:space="preserve"> + <source>%s insecure extension(s) found</source> + </trans-unit> + <trans-unit id="report.status.loadedExtensions.insecureExtensionLoaded.message" xml:space="preserve"> + <source>The following extensions are insecure and usage might damage your system. Please update these extensions as soon as possible or remove them from your system:<br><br>%s</source> + </trans-unit> + <trans-unit id="report.status.loadedExtensions.insecureExtensionLoaded.message.extension" xml:space="preserve"> + <source><strong>%1s</strong> (version %2s)<br></source> + </trans-unit> + <trans-unit id="report.status.existingExtensions.title" xml:space="preserve"> + <source>Security status of existing, but not loaded extensions</source> + </trans-unit> + <trans-unit id="report.status.existingExtensions.noInsecureExtensionExists.value" xml:space="preserve"> + <source>OK</source> + </trans-unit> + <trans-unit id="report.status.existingExtensions.insecureExtensionExists.value" xml:space="preserve"> + <source>%s insecure extension(s) found</source> + </trans-unit> + <trans-unit id="report.status.existingExtensions.insecureExtensionExists.message" xml:space="preserve"> + <source>The following extensions were found on your system, but are currently not installed. Please delete the extensions using the extension manager:<br><br>%s</source> + </trans-unit> + <trans-unit id="report.status.existingExtensions.insecureExtensionExists.message.extension" xml:space="preserve"> + <source><strong>%1s</strong> (version %2s)<br></source> + </trans-unit> </body> </file> </xliff> diff --git a/typo3/sysext/extensionmanager/Tests/Unit/Domain/Repository/RepositoryRepositoryTest.php b/typo3/sysext/extensionmanager/Tests/Unit/Domain/Repository/RepositoryRepositoryTest.php new file mode 100644 index 0000000000000000000000000000000000000000..15b5d4261a91ae4ae628f305b71762a1ca9c4b7a --- /dev/null +++ b/typo3/sysext/extensionmanager/Tests/Unit/Domain/Repository/RepositoryRepositoryTest.php @@ -0,0 +1,75 @@ +<?php +namespace TYPO3\CMS\Extensionmanager\Tests\Unit\Domain\Repository; + +/*************************************************************** + * Copyright notice + * + * (c) 2012 Chritian Kuhn, <lolli@schwarzbu.ch> + * 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! + ***************************************************************/ + +/** + * Test case + * + * @author Christian Kuhn <lolli@schwarzbu.ch> + */ +class RepositoryRepositoryTest extends \TYPO3\CMS\Extbase\Tests\Unit\BaseTestCase { + + /** + * @test + */ + public function findOneTypo3OrgRepositoryReturnsNullIfNoRepositoryWithThisTitleExists() { + /** @var $fixture \TYPO3\CMS\Extensionmanager\Domain\Repository\RepositoryRepository|\PHPUnit_Framework_MockObject_MockObject */ + $fixture = $this->getMock('TYPO3\\CMS\\Extensionmanager\\Domain\\Repository\\RepositoryRepository', array('findAll')); + $fixture + ->expects($this->once()) + ->method('findAll') + ->will($this->returnValue(array())); + + $this->assertNull($fixture->findOneTypo3OrgRepository()); + } + + /** + * @test + */ + public function findOneTypo3OrgRepositoryReturnsRepositoryWithCorrectTitle() { + $mockModelOne = $this->getMock('TYPO3\\CMS\\Extensionmanager\\Domain\\Model\\Repository'); + $mockModelOne + ->expects(($this->once())) + ->method('getTitle') + ->will($this->returnValue('foo')); + $mockModelTwo = $this->getMock('TYPO3\\CMS\\Extensionmanager\\Domain\\Model\\Repository'); + $mockModelTwo + ->expects(($this->once())) + ->method('getTitle') + ->will($this->returnValue('TYPO3.org Main Repository')); + + /** @var $fixture \TYPO3\CMS\Extensionmanager\Domain\Repository\RepositoryRepository|\PHPUnit_Framework_MockObject_MockObject */ + $fixture = $this->getMock('TYPO3\\CMS\\Extensionmanager\\Domain\\Repository\\RepositoryRepository', array('findAll')); + $fixture + ->expects($this->once()) + ->method('findAll') + ->will($this->returnValue(array($mockModelOne, $mockModelTwo))); + + $this->assertSame($mockModelTwo, $fixture->findOneTypo3OrgRepository()); + } +} + + +?> \ No newline at end of file diff --git a/typo3/sysext/extensionmanager/Tests/Unit/Report/ExtensionStatusTest.php b/typo3/sysext/extensionmanager/Tests/Unit/Report/ExtensionStatusTest.php new file mode 100644 index 0000000000000000000000000000000000000000..14d9f416f3c958826a545172658d6eaf3ef3c557 --- /dev/null +++ b/typo3/sysext/extensionmanager/Tests/Unit/Report/ExtensionStatusTest.php @@ -0,0 +1,304 @@ +<?php +namespace TYPO3\CMS\Extensionmanager\Tests\Unit\Report; +use TYPO3\CMS\Extensionmanager\Report; + +/*************************************************************** + * Copyright notice + * + * (c) 2010-2012 Christian Kuhn <lolli@schwarzbu.ch> + * 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! + ***************************************************************/ + +/** + * Test case + * + * @author Christian Kuhn <lolli@schwarzbu.ch> + */ +class ExtensionStatusTest extends \TYPO3\CMS\Extbase\Tests\Unit\BaseTestCase { + + /** + * @test + */ + public function extensionStatusImplementsStatusProviderInterface() { + $reportMock = $this->getMock('TYPO3\\CMS\\Extensionmanager\\Report\\ExtensionStatus'); + $this->assertInstanceOf('TYPO3\\CMS\\Reports\\StatusProviderInterface', $reportMock); + } + + /** + * @test + */ + public function getStatusReturnsArray() { + $report = new Report\ExtensionStatus(); + $this->assertInternalType('array', $report->getStatus()); + } + + /** + * @test + */ + public function getStatusReturnArrayContainsThreeEntries() { + $report = new Report\ExtensionStatus(); + $this->assertSame(3, count($report->getStatus())); + } + + /** + * @test + */ + public function getStatusReturnArrayContainsInstancesOfReportsStatusStatus() { + $report = new Report\ExtensionStatus(); + $resultStatuses = $report->getStatus(); + foreach($resultStatuses as $status) { + $this->assertInstanceOf('TYPO3\\CMS\\Reports\\Status', $status); + } + } + + /** + * @test + */ + public function getStatusCallsGetMainRepositoryStatusForMainRepositoryStatusResult() { + /** @var $mockReport \TYPO3\CMS\Extensionmanager\Report\ExtensionStatus|\PHPUnit_Framework_MockObject_MockObject */ + $mockReport = $this->getMock('TYPO3\\CMS\\Extensionmanager\\Report\\ExtensionStatus', array('getMainRepositoryStatus')); + $mockReport + ->expects($this->once()) + ->method('getMainRepositoryStatus') + ->will($this->returnValue('foo')); + $result = $mockReport->getStatus(); + $this->assertSame('foo', $result['mainRepositoryStatus']); + } + + /** + * @test + */ + public function getMainRepositoryStatusReturnsErrorStatusIfRepositoryIsNotFound() { + /** @var $mockRepositoryRepository \TYPO3\CMS\Extensionmanager\Domain\Repository\RepositoryRepository|\PHPUnit_Framework_MockObject_MockObject */ + $mockRepositoryRepository = $this->getMock('TYPO3\\CMS\\Extensionmanager\\Domain\\Repository\\RepositoryRepository'); + $mockRepositoryRepository + ->expects($this->once()) + ->method('findOneTypo3OrgRepository') + ->will($this->returnValue(NULL)); + + /** @var $mockReport \TYPO3\CMS\Extensionmanager\Report\ExtensionStatus|\PHPUnit_Framework_MockObject_MockObject|\TYPO3\CMS\Core\Tests\AccessibleObjectInterface */ + $mockReport = $this->getAccessibleMock('TYPO3\\CMS\\Extensionmanager\\Report\\ExtensionStatus', array('dummy')); + $mockReport->_set('repositoryRepository', $mockRepositoryRepository); + + /** @var $result \TYPO3\CMS\Reports\Status */ + $result = $mockReport->_call('getMainRepositoryStatus'); + $this->assertSame(\TYPO3\CMS\Reports\Status::ERROR, $result->getSeverity()); + } + + /** + * @test + */ + public function getMainRepositoryStatusReturnsNoticeIfRepositoryUpdateIsLongerThanSevenDaysAgo() { + /** @var $mockRepositoryRepository \TYPO3\CMS\Extensionmanager\Domain\Model\Repository|\PHPUnit_Framework_MockObject_MockObject */ + $mockRepository = $this->getMock('TYPO3\\CMS\\Extensionmanager\\Domain\\Model\\Repository'); + $mockRepository + ->expects($this->once()) + ->method('getLastUpdate') + ->will($this->returnValue(new \DateTime('-8 days'))); + + /** @var $mockRepositoryRepository \TYPO3\CMS\Extensionmanager\Domain\Repository\RepositoryRepository|\PHPUnit_Framework_MockObject_MockObject */ + $mockRepositoryRepository = $this->getMock('TYPO3\\CMS\\Extensionmanager\\Domain\\Repository\\RepositoryRepository'); + $mockRepositoryRepository + ->expects($this->once()) + ->method('findOneTypo3OrgRepository') + ->will($this->returnValue($mockRepository)); + + /** @var $mockReport \TYPO3\CMS\Extensionmanager\Report\ExtensionStatus|\PHPUnit_Framework_MockObject_MockObject|\TYPO3\CMS\Core\Tests\AccessibleObjectInterface */ + $mockReport = $this->getAccessibleMock('TYPO3\\CMS\\Extensionmanager\\Report\\ExtensionStatus', array('dummy')); + $mockReport->_set('repositoryRepository', $mockRepositoryRepository); + + /** @var $result \TYPO3\CMS\Reports\Status */ + $result = $mockReport->_call('getMainRepositoryStatus'); + $this->assertSame(\TYPO3\CMS\Reports\Status::NOTICE, $result->getSeverity()); + } + + /** + * @test + */ + public function getMainRepositoryStatusReturnsOkIfUpdatedLessThanSevenDaysAgo() { + /** @var $mockRepositoryRepository \TYPO3\CMS\Extensionmanager\Domain\Model\Repository|\PHPUnit_Framework_MockObject_MockObject */ + $mockRepository = $this->getMock('TYPO3\\CMS\\Extensionmanager\\Domain\\Model\\Repository'); + $mockRepository + ->expects($this->once()) + ->method('getLastUpdate') + ->will($this->returnValue(new \DateTime('-6 days'))); + + /** @var $mockRepositoryRepository \TYPO3\CMS\Extensionmanager\Domain\Repository\RepositoryRepository|\PHPUnit_Framework_MockObject_MockObject */ + $mockRepositoryRepository = $this->getMock('TYPO3\\CMS\\Extensionmanager\\Domain\\Repository\\RepositoryRepository'); + $mockRepositoryRepository + ->expects($this->once()) + ->method('findOneTypo3OrgRepository') + ->will($this->returnValue($mockRepository)); + + /** @var $mockReport \TYPO3\CMS\Extensionmanager\Report\ExtensionStatus|\PHPUnit_Framework_MockObject_MockObject|\TYPO3\CMS\Core\Tests\AccessibleObjectInterface */ + $mockReport = $this->getAccessibleMock('TYPO3\\CMS\\Extensionmanager\\Report\\ExtensionStatus', array('dummy')); + $mockReport->_set('repositoryRepository', $mockRepositoryRepository); + + /** @var $result \TYPO3\CMS\Reports\Status */ + $result = $mockReport->_call('getMainRepositoryStatus'); + $this->assertSame(\TYPO3\CMS\Reports\Status::OK, $result->getSeverity()); + } + + /** + * @test + */ + public function getSecurityStatusOfExtensionsReturnsOkForLoadedExtensionIfNoInsecureExtensionIsLoaded() { + /** @var $mockTerObject \TYPO3\CMS\Extensionmanager\Domain\Model\Extension|\PHPUnit_Framework_MockObject_MockObject */ + $mockTerObject = $this->getMock('TYPO3\\CMS\\Extensionmanager\\Domain\\Model\\Extension'); + $mockTerObject + ->expects($this->any()) + ->method('getVersion') + ->will($this->returnValue('1.0.6')); + $mockTerObject + ->expects($this->atLeastOnce()) + ->method('getReviewState') + ->will($this->returnValue(0)); + $mockExtensionList = array( + 'enetcache' => array( + 'installed' => TRUE, + 'terObject' => $mockTerObject + ), + ); + /** @var $mockListUtility \TYPO3\CMS\Extensionmanager\Utility\ListUtility|\PHPUnit_Framework_MockObject_MockObject */ + $mockListUtility = $this->getMock('TYPO3\\CMS\\Extensionmanager\\Utility\\ListUtility'); + $mockListUtility + ->expects($this->once()) + ->method('getAvailableAndInstalledExtensionsWithAdditionalInformation') + ->will($this->returnValue($mockExtensionList)); + + /** @var $mockReport \TYPO3\CMS\Extensionmanager\Report\ExtensionStatus|\PHPUnit_Framework_MockObject_MockObject|\TYPO3\CMS\Core\Tests\AccessibleObjectInterface */ + $mockReport = $this->getAccessibleMock('TYPO3\\CMS\\Extensionmanager\\Report\\ExtensionStatus', array('dummy')); + $mockReport->_set('listUtility', $mockListUtility); + + $result = $mockReport->_call('getSecurityStatusOfExtensions'); + /** @var $loadedResult \TYPO3\CMS\Reports\Status */ + $loadedResult = $result->loaded; + $this->assertSame(\TYPO3\CMS\Reports\Status::OK, $loadedResult->getSeverity()); + } + + /** + * @test + */ + public function getSecurityStatusOfExtensionsReturnsErrorForLoadedExtensionIfInsecureExtensionIsLoaded() { + /** @var $mockTerObject \TYPO3\CMS\Extensionmanager\Domain\Model\Extension|\PHPUnit_Framework_MockObject_MockObject */ + $mockTerObject = $this->getMock('TYPO3\\CMS\\Extensionmanager\\Domain\\Model\\Extension'); + $mockTerObject + ->expects($this->any()) + ->method('getVersion') + ->will($this->returnValue('1.0.6')); + $mockTerObject + ->expects($this->atLeastOnce()) + ->method('getReviewState') + ->will($this->returnValue(-1)); + $mockExtensionList = array( + 'enetcache' => array( + 'installed' => TRUE, + 'terObject' => $mockTerObject + ), + ); + /** @var $mockListUtility \TYPO3\CMS\Extensionmanager\Utility\ListUtility|\PHPUnit_Framework_MockObject_MockObject */ + $mockListUtility = $this->getMock('TYPO3\\CMS\\Extensionmanager\\Utility\\ListUtility'); + $mockListUtility + ->expects($this->once()) + ->method('getAvailableAndInstalledExtensionsWithAdditionalInformation') + ->will($this->returnValue($mockExtensionList)); + + /** @var $mockReport \TYPO3\CMS\Extensionmanager\Report\ExtensionStatus|\PHPUnit_Framework_MockObject_MockObject|\TYPO3\CMS\Core\Tests\AccessibleObjectInterface */ + $mockReport = $this->getAccessibleMock('TYPO3\\CMS\\Extensionmanager\\Report\\ExtensionStatus', array('dummy')); + $mockReport->_set('listUtility', $mockListUtility); + + $result = $mockReport->_call('getSecurityStatusOfExtensions'); + /** @var $loadedResult \TYPO3\CMS\Reports\Status */ + $loadedResult = $result->loaded; + $this->assertSame(\TYPO3\CMS\Reports\Status::ERROR, $loadedResult->getSeverity()); + } + + /** + * @test + */ + public function getSecurityStatusOfExtensionsReturnsOkForExistingExtensionIfNoInsecureExtensionExists() { + /** @var $mockTerObject \TYPO3\CMS\Extensionmanager\Domain\Model\Extension|\PHPUnit_Framework_MockObject_MockObject */ + $mockTerObject = $this->getMock('TYPO3\\CMS\\Extensionmanager\\Domain\\Model\\Extension'); + $mockTerObject + ->expects($this->any()) + ->method('getVersion') + ->will($this->returnValue('1.0.6')); + $mockTerObject + ->expects($this->atLeastOnce()) + ->method('getReviewState') + ->will($this->returnValue(0)); + $mockExtensionList = array( + 'enetcache' => array( + 'terObject' => $mockTerObject + ), + ); + /** @var $mockListUtility \TYPO3\CMS\Extensionmanager\Utility\ListUtility|\PHPUnit_Framework_MockObject_MockObject */ + $mockListUtility = $this->getMock('TYPO3\\CMS\\Extensionmanager\\Utility\\ListUtility'); + $mockListUtility + ->expects($this->once()) + ->method('getAvailableAndInstalledExtensionsWithAdditionalInformation') + ->will($this->returnValue($mockExtensionList)); + + /** @var $mockReport \TYPO3\CMS\Extensionmanager\Report\ExtensionStatus|\PHPUnit_Framework_MockObject_MockObject|\TYPO3\CMS\Core\Tests\AccessibleObjectInterface */ + $mockReport = $this->getAccessibleMock('TYPO3\\CMS\\Extensionmanager\\Report\\ExtensionStatus', array('dummy')); + $mockReport->_set('listUtility', $mockListUtility); + + $result = $mockReport->_call('getSecurityStatusOfExtensions'); + /** @var $existingResult \TYPO3\CMS\Reports\Status */ + $existingResult = $result->existing; + $this->assertSame(\TYPO3\CMS\Reports\Status::OK, $existingResult->getSeverity()); + } + + /** + * @test + */ + public function getSecurityStatusOfExtensionsReturnsErrorForExistingExtensionIfInsecureExtensionExists() { + /** @var $mockTerObject \TYPO3\CMS\Extensionmanager\Domain\Model\Extension|\PHPUnit_Framework_MockObject_MockObject */ + $mockTerObject = $this->getMock('TYPO3\\CMS\\Extensionmanager\\Domain\\Model\\Extension'); + $mockTerObject + ->expects($this->any()) + ->method('getVersion') + ->will($this->returnValue('1.0.6')); + $mockTerObject + ->expects($this->atLeastOnce()) + ->method('getReviewState') + ->will($this->returnValue(-1)); + $mockExtensionList = array( + 'enetcache' => array( + 'terObject' => $mockTerObject + ), + ); + /** @var $mockListUtility \TYPO3\CMS\Extensionmanager\Utility\ListUtility|\PHPUnit_Framework_MockObject_MockObject */ + $mockListUtility = $this->getMock('TYPO3\\CMS\\Extensionmanager\\Utility\\ListUtility'); + $mockListUtility + ->expects($this->once()) + ->method('getAvailableAndInstalledExtensionsWithAdditionalInformation') + ->will($this->returnValue($mockExtensionList)); + + /** @var $mockReport \TYPO3\CMS\Extensionmanager\Report\ExtensionStatus|\PHPUnit_Framework_MockObject_MockObject|\TYPO3\CMS\Core\Tests\AccessibleObjectInterface */ + $mockReport = $this->getAccessibleMock('TYPO3\\CMS\\Extensionmanager\\Report\\ExtensionStatus', array('dummy')); + $mockReport->_set('listUtility', $mockListUtility); + + $result = $mockReport->_call('getSecurityStatusOfExtensions'); + /** @var $existingResult \TYPO3\CMS\Reports\Status */ + $existingResult = $result->existing; + $this->assertSame(\TYPO3\CMS\Reports\Status::WARNING, $existingResult->getSeverity()); + } +} +?> \ No newline at end of file diff --git a/typo3/sysext/extensionmanager/Tests/Unit/Task/UpdateExtensionListTaskTest.php b/typo3/sysext/extensionmanager/Tests/Unit/Task/UpdateExtensionListTaskTest.php index 4844e62ffa3c8381ceab6fc993d366225643356d..6074b2f5ee1d1189c743cfc8ddbf80ce026550aa 100644 --- a/typo3/sysext/extensionmanager/Tests/Unit/Task/UpdateExtensionListTaskTest.php +++ b/typo3/sysext/extensionmanager/Tests/Unit/Task/UpdateExtensionListTaskTest.php @@ -50,6 +50,14 @@ class UpdateExtensionListTaskTest extends \TYPO3\CMS\Extbase\Tests\Unit\BaseTest \TYPO3\CMS\Core\Utility\GeneralUtility::resetSingletonInstances($this->singletonInstances); } + /** + * @test + */ + public function updateExtensionListTaskIsInstanceOfAbstractTask() { + $taskMock = $this->getMock('TYPO3\CMS\Extensionmanager\Task\\UpdateExtensionListTask'); + $this->assertInstanceOf('TYPO3\\CMS\\Scheduler\\Task\\AbstractTask', $taskMock); + } + /** * @test */ diff --git a/typo3/sysext/extensionmanager/ext_tables.php b/typo3/sysext/extensionmanager/ext_tables.php index 6d6bd3eb5a9d64a27cacb77e9b1989287138bfea..c7c97f974b1858c9cb0e96f03e253d9da880f199 100644 --- a/typo3/sysext/extensionmanager/ext_tables.php +++ b/typo3/sysext/extensionmanager/ext_tables.php @@ -41,6 +41,9 @@ if (TYPO3_MODE === 'BE') { 'labels' => 'LLL:EXT:' . $_EXTKEY . '/Resources/Private/Language/locallang_mod.xml', ) ); -} + // Register extension status report system + $GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['reports']['tx_reports']['status']['providers']['Extension Manager'][] = + 'TYPO3\\CMS\\Extensionmanager\\Report\\ExtensionStatus'; +} ?> \ No newline at end of file diff --git a/typo3/sysext/reports/Classes/Status.php b/typo3/sysext/reports/Classes/Status.php index 59f5c19398cf26c37fe56c30820a8ce6b1d2c890..ddf9e93cd9349a703ed2c3a0d1e6388ccdd0f6d1 100644 --- a/typo3/sysext/reports/Classes/Status.php +++ b/typo3/sysext/reports/Classes/Status.php @@ -58,12 +58,16 @@ class Status { protected $severity; /** - * constructor for class tx_reports_report_status_Status + * Construct a status * - * @param string $title The status' title - * @param string $value The status' value - * @param string $message An optional message further describing the status - * @param integer $severity A severity level, one of + * All values must be given as constructor arguments. + * All strings should be localized. + * + * @param string $title Status title, eg. "Deprecation log" + * @param string $value Status value, eg. "Disabled" + * @param string $message Optional message further describing the title/value combination + * Example:, eg "The deprecation log is imporant and does foo, to disable it do bar" + * @param integer $severity A severity level. Use one of the constants above! */ public function __construct($title, $value, $message = '', $severity = self::OK) { $this->title = (string) $title;