[TASK] Split DataHandler::copyRecord_procBasedOnFieldType
[Packages/TYPO3.CMS.git] / typo3 / sysext / core / Tests / FunctionalTestCase.php
index 0a33d2b..34e8535 100644 (file)
@@ -1,28 +1,20 @@
 <?php
 namespace TYPO3\CMS\Core\Tests;
 
-/***************************************************************
- * Copyright notice
+/*
+ * This file is part of the TYPO3 CMS project.
  *
- * (c) 2013 Christian Kuhn <lolli@schwarzbu.ch>
- * All rights reserved
+ * It is free software; you can redistribute it and/or modify it under
+ * the terms of the GNU General Public License, either version 2
+ * of the License, or any later version.
  *
- * 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.
+ * For the full copyright and license information, please read the
+ * LICENSE.txt file that was distributed with this source code.
  *
- * 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!
- ***************************************************************/
+ * The TYPO3 project - inspiring people to share!
+ */
+
+use TYPO3\CMS\Core\Tests\Functional\Framework\Frontend\Response;
 
 /**
  * Base test case class for functional tests, all TYPO3 CMS
@@ -52,10 +44,9 @@ namespace TYPO3\CMS\Core\Tests;
  * - ./typo3conf/ext/phpunit/Composer/vendor/bin/phpunit \
  *     --process-isolation \
  *     --bootstrap typo3/sysext/core/Build/FunctionalTestsBootstrap.php \
- *     typo3/sysext/core/Tests/Functional/Functional/FunctionalTestCaseTest.php
+ *     typo3/sysext/core/Tests/Functional/DataHandling/DataHandlerTest.php
  */
 abstract class FunctionalTestCase extends BaseTestCase {
-
        /**
         * Core extensions to load.
         *
@@ -68,10 +59,9 @@ abstract class FunctionalTestCase extends BaseTestCase {
         * be loaded for every test of a test case and it is not possible to change
         * the list of loaded extensions between single tests of a test case.
         *
-        * Required core extensions like core, cms, extbase and so on are loaded
-        * automatically, so there is no need to add them here. See constant
-        * REQUIRED_EXTENSIONS for a list of automatically loaded extensions.
+        * A default list of core extensions is always loaded.
         *
+        * @see FunctionalTestCaseUtility $defaultActivatedCoreExtensions
         * @var array
         */
        protected $coreExtensionsToLoad = array();
@@ -99,6 +89,70 @@ abstract class FunctionalTestCase extends BaseTestCase {
        protected $testExtensionsToLoad = array();
 
        /**
+        * Array of test/fixture folder or file paths that should be linked for a test.
+        *
+        * This property will stay empty in this abstract, so it is possible
+        * to just overwrite it in extending classes. Path noted here will
+        * be linked for every test of a test case and it is not possible to change
+        * the list of folders between single tests of a test case.
+        *
+        * array(
+        *   'link-source' => 'link-destination'
+        * );
+        *
+        * Given paths are expected to be relative to the test instance root.
+        * The array keys are the source paths and the array values are the destination
+        * paths, example:
+        *
+        * array(
+        *   'typo3/sysext/impext/Tests/Functional/Fixtures/Folders/fileadmin/user_upload' =>
+        *   'fileadmin/user_upload',
+        *   'typo3conf/ext/my_own_ext/Tests/Functional/Fixtures/Folders/uploads/tx_myownext' =>
+        *   'uploads/tx_myownext'
+        * );
+        *
+        * To be able to link from my_own_ext the extension path needs also to be registered in
+        * property $testExtensionsToLoad
+        *
+        * @var array
+        */
+       protected $pathsToLinkInTestInstance = array();
+
+       /**
+        * This configuration array is merged with TYPO3_CONF_VARS
+        * that are set in default configuration and factory configuration
+        *
+        * @var array
+        */
+       protected $configurationToUseInTestInstance = array();
+
+       /**
+        * Array of folders that should be created inside the test instance document root.
+        *
+        * This property will stay empty in this abstract, so it is possible
+        * to just overwrite it in extending classes. Path noted here will
+        * be linked for every test of a test case and it is not possible to change
+        * the list of folders between single tests of a test case.
+        *
+        * Per default the following folder are created
+        * /fileadmin
+        * /typo3temp
+        * /typo3conf
+        * /typo3conf/ext
+        * /uploads
+        *
+        * To create additional folders add the paths to this array. Given paths are expected to be
+        * relative to the test instance root and have to begin with a slash. Example:
+        *
+        * array(
+        *   'fileadmin/user_upload'
+        * );
+        *
+        * @var array
+        */
+       protected $additionalFoldersToCreate = array();
+
+       /**
         * Private utility class used in setUp() and tearDown(). Do NOT use in test cases!
         *
         * @var \TYPO3\CMS\Core\Tests\FunctionalTestCaseBootstrapUtility
@@ -106,36 +160,32 @@ abstract class FunctionalTestCase extends BaseTestCase {
        private $bootstrapUtility = NULL;
 
        /**
+        * Path to TYPO3 CMS test installation for this test case
+        *
+        * @var string
+        */
+       private $instancePath;
+
+       /**
         * Set up creates a test instance and database.
         *
         * This method should be called with parent::setUp() in your test cases!
         *
         * @return void
         */
-       public function setUp() {
+       protected function setUp() {
                if (!defined('ORIGINAL_ROOT')) {
                        $this->markTestSkipped('Functional tests must be called through phpunit on CLI');
                }
                $this->bootstrapUtility = new FunctionalTestCaseBootstrapUtility();
-               $this->bootstrapUtility->setUp(get_class($this), $this->coreExtensionsToLoad, $this->testExtensionsToLoad);
-       }
-
-       /**
-        * Tear down destroys the instance and database.
-        *
-        * This method should be called with parent::tearDown() in your test cases!
-        *
-        * @throws Exception
-        * @return void
-        */
-       public function tearDown() {
-               if (!($this->bootstrapUtility instanceof FunctionalTestCaseBootstrapUtility)) {
-                       throw new Exception(
-                               'Bootstrap utility not set. Is parent::setUp() called in setUp()?',
-                               1376826527
-                       );
-               }
-               $this->bootstrapUtility->tearDown();
+               $this->instancePath = $this->bootstrapUtility->setUp(
+                       get_class($this),
+                       $this->coreExtensionsToLoad,
+                       $this->testExtensionsToLoad,
+                       $this->pathsToLinkInTestInstance,
+                       $this->configurationToUseInTestInstance,
+                       $this->additionalFoldersToCreate
+               );
        }
 
        /**
@@ -146,11 +196,45 @@ abstract class FunctionalTestCase extends BaseTestCase {
         *
         * @return \TYPO3\CMS\Core\Database\DatabaseConnection
         */
-       protected function getDatabase() {
+       protected function getDatabaseConnection() {
                return $GLOBALS['TYPO3_DB'];
        }
 
        /**
+        * Initialize backend user
+        *
+        * @param int $userUid uid of the user we want to initialize. This user must exist in the fixture file
+        * @return \TYPO3\CMS\Core\Authentication\BackendUserAuthentication
+        * @throws Exception
+        */
+       protected function setUpBackendUserFromFixture($userUid) {
+               $this->importDataSet(ORIGINAL_ROOT . 'typo3/sysext/core/Tests/Functional/Fixtures/be_users.xml');
+               $database = $this->getDatabaseConnection();
+               $userRow = $database->exec_SELECTgetSingleRow('*', 'be_users', 'uid = ' . (int)$userUid);
+
+               /** @var $backendUser \TYPO3\CMS\Core\Authentication\BackendUserAuthentication */
+               $backendUser = \TYPO3\CMS\Core\Utility\GeneralUtility::makeInstance(\TYPO3\CMS\Core\Authentication\BackendUserAuthentication::class);
+               $sessionId = $backendUser->createSessionId();
+               $_COOKIE['be_typo_user'] = $sessionId;
+               $backendUser->id = $sessionId;
+               $backendUser->sendNoCacheHeaders = FALSE;
+               $backendUser->dontSetCookie = TRUE;
+               $backendUser->createUserSession($userRow);
+
+               $GLOBALS['BE_USER'] = $backendUser;
+               $GLOBALS['BE_USER']->start();
+               if (!is_array($GLOBALS['BE_USER']->user) || !$GLOBALS['BE_USER']->user['uid']) {
+                       throw new Exception(
+                               'Can not initialize backend user',
+                               1377095807
+                       );
+               }
+               $GLOBALS['BE_USER']->backendCheckLogin();
+
+               return $backendUser;
+       }
+
+       /**
         * Imports a data set represented as XML into the test database,
         *
         * @param string $path Absolute path to the XML file containing the data set to load
@@ -165,7 +249,7 @@ abstract class FunctionalTestCase extends BaseTestCase {
                        );
                }
 
-               $database = $this->getDatabase();
+               $database = $this->getDatabaseConnection();
 
                $xml = simplexml_load_file($path);
                $foreignKeys = array();
@@ -185,20 +269,112 @@ abstract class FunctionalTestCase extends BaseTestCase {
                                } elseif (isset($column['is-NULL']) && ($column['is-NULL'] === 'yes')) {
                                        $columnValue = NULL;
                                } else {
-                                       $columnValue = $table->$columnName;
+                                       $columnValue = (string)$table->$columnName;
                                }
 
                                $insertArray[$columnName] = $columnValue;
                        }
 
                        $tableName = $table->getName();
-                       $database->exec_INSERTquery($tableName, $insertArray);
-
+                       $result = $database->exec_INSERTquery($tableName, $insertArray);
+                       if ($result === FALSE) {
+                               throw new Exception(
+                                       'Error when processing fixture file: ' . $path . ' Can not insert data to table ' . $tableName . ': ' . $database->sql_error(),
+                                       1376746262
+                               );
+                       }
                        if (isset($table['id'])) {
-                               $elementId = (string) $table['id'];
+                               $elementId = (string)$table['id'];
                                $foreignKeys[$tableName][$elementId] = $database->sql_insert_id();
                        }
                }
        }
+
+       /**
+        * @param int $pageId
+        * @param array $typoScriptFiles
+        */
+       protected function setUpFrontendRootPage($pageId, array $typoScriptFiles = array()) {
+               $pageId = (int)$pageId;
+               $page = $this->getDatabaseConnection()->exec_SELECTgetSingleRow('*', 'pages', 'uid=' . $pageId);
+
+               if (empty($page)) {
+                       $this->fail('Cannot set up frontend root page "' . $pageId . '"');
+               }
+
+               $pagesFields = array(
+                       'is_siteroot' => 1
+               );
+
+               $this->getDatabaseConnection()->exec_UPDATEquery('pages', 'uid=' . $pageId, $pagesFields);
+
+               $templateFields = array(
+                       'pid' => $pageId,
+                       'title' => '',
+                       'config' => '',
+                       'clear' => 3,
+                       'root' => 1,
+               );
+
+               foreach ($typoScriptFiles as $typoScriptFile) {
+                       $templateFields['config'] .= '<INCLUDE_TYPOSCRIPT: source="FILE:' . $typoScriptFile . '">' . LF;
+               }
+
+               $this->getDatabaseConnection()->exec_INSERTquery('sys_template', $templateFields);
+       }
+
+       /**
+        * @param int $pageId
+        * @param int $languageId
+        * @param int $backendUserId
+        * @param int $workspaceId
+        * @param bool $failOnFailure
+        * @param int $frontendUserId
+        * @return Response
+        */
+       protected function getFrontendResponse($pageId, $languageId = 0, $backendUserId = 0, $workspaceId = 0, $failOnFailure = TRUE, $frontendUserId = 0) {
+               $pageId = (int)$pageId;
+               $languageId = (int)$languageId;
+
+               $additionalParameter = '';
+
+               if (!empty($frontendUserId)) {
+                       $additionalParameter .= '&frontendUserId=' . (int)$frontendUserId;
+               }
+               if (!empty($backendUserId)) {
+                       $additionalParameter .= '&backendUserId=' . (int)$backendUserId;
+               }
+               if (!empty($workspaceId)) {
+                       $additionalParameter .= '&workspaceId=' . (int)$workspaceId;
+               }
+
+               $arguments = array(
+                       'documentRoot' => $this->instancePath,
+                       'requestUrl' => 'http://localhost/?id=' . $pageId . '&L=' . $languageId . $additionalParameter,
+               );
+
+               $template = new \Text_Template(ORIGINAL_ROOT . 'typo3/sysext/core/Tests/Functional/Fixtures/Frontend/request.tpl');
+               $template->setVar(
+                       array(
+                               'arguments' => var_export($arguments, TRUE),
+                               'originalRoot' => ORIGINAL_ROOT,
+                       )
+               );
+
+               $php = \PHPUnit_Util_PHP::factory();
+               $response = $php->runJob($template->render());
+               $result = json_decode($response['stdout'], TRUE);
+
+               if ($result === NULL) {
+                       $this->fail('Frontend Response is empty');
+               }
+
+               if ($failOnFailure && $result['status'] === Response::STATUS_Failure) {
+                       $this->fail('Frontend Response has failure:' . LF . $result['error']);
+               }
+
+               $response = new Response($result['status'], $result['content'], $result['error']);
+               return $response;
+       }
+
 }
-?>
\ No newline at end of file