[TASK] Re-implement extension status for reports module
authorChristian Kuhn <lolli@schwarzbu.ch>
Sun, 4 Nov 2012 21:44:36 +0000 (22:44 +0100)
committerChristian Kuhn <lolli@schwarzbu.ch>
Wed, 14 Nov 2012 19:48:51 +0000 (20:48 +0100)
The reports module to show the main typo3.org TER repository
extension list status and the security state of loaded and
existing extensions was not implemented with the new
extension manager.
The patch adds the missing reports.

Resolves: #39914
Releases: 6.0

Change-Id: Ib26dad4d798829ee96d900a80311aa28bb021c2c
Reviewed-on: http://review.typo3.org/16446
Reviewed-by: Wouter Wolters
Tested-by: Wouter Wolters
Reviewed-by: Anja Leichsenring
Tested-by: Anja Leichsenring
Reviewed-by: Christian Kuhn
Tested-by: Christian Kuhn
typo3/sysext/extensionmanager/Classes/Domain/Repository/ExtensionRepository.php
typo3/sysext/extensionmanager/Classes/Domain/Repository/RepositoryRepository.php
typo3/sysext/extensionmanager/Classes/Report/ExtensionStatus.php [new file with mode: 0644]
typo3/sysext/extensionmanager/Classes/Utility/ListUtility.php
typo3/sysext/extensionmanager/Resources/Private/Language/locallang.xlf
typo3/sysext/extensionmanager/Tests/Unit/Domain/Repository/RepositoryRepositoryTest.php [new file with mode: 0644]
typo3/sysext/extensionmanager/Tests/Unit/Report/ExtensionStatusTest.php [new file with mode: 0644]
typo3/sysext/extensionmanager/Tests/Unit/Task/UpdateExtensionListTaskTest.php
typo3/sysext/extensionmanager/ext_tables.php
typo3/sysext/reports/Classes/Status.php

index a1ca137..c14376f 100644 (file)
@@ -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();
        }
index 945ea89..b9eefad 100644 (file)
@@ -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 (file)
index 0000000..33af3f8
--- /dev/null
@@ -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
index 72b5f35..f62dd89 100644 (file)
@@ -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
index 1469273..3d27bf8 100644 (file)
                        <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:&lt;br&gt;&lt;br&gt;%s</source>
+                       </trans-unit>
+                       <trans-unit id="report.status.loadedExtensions.insecureExtensionLoaded.message.extension" xml:space="preserve">
+                               <source>&lt;strong&gt;%1s&lt;/strong&gt; (version %2s)&lt;br&gt;</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:&lt;br&gt;&lt;br&gt;%s</source>
+                       </trans-unit>
+                       <trans-unit id="report.status.existingExtensions.insecureExtensionExists.message.extension" xml:space="preserve">
+                               <source>&lt;strong&gt;%1s&lt;/strong&gt; (version %2s)&lt;br&gt;</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 (file)
index 0000000..15b5d42
--- /dev/null
@@ -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 (file)
index 0000000..14d9f41
--- /dev/null
@@ -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
index 4844e62..6074b2f 100644 (file)
@@ -53,6 +53,14 @@ class UpdateExtensionListTaskTest extends \TYPO3\CMS\Extbase\Tests\Unit\BaseTest
        /**
         * @test
         */
+       public function updateExtensionListTaskIsInstanceOfAbstractTask() {
+               $taskMock = $this->getMock('TYPO3\CMS\Extensionmanager\Task\\UpdateExtensionListTask');
+               $this->assertInstanceOf('TYPO3\\CMS\\Scheduler\\Task\\AbstractTask', $taskMock);
+       }
+
+       /**
+        * @test
+        */
        public function executeCallsUpdateExtListOfRepositoryHelper() {
                $repositoryHelperMock = $this->getMock('TYPO3\\CMS\\Extensionmanager\\Utility\\Repository\\Helper');
                $repositoryHelperMock
index 6d6bd3e..c7c97f9 100644 (file)
@@ -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
index 59f5c19..ddf9e93 100644 (file)
@@ -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;