├── .gitignore ├── AllTestsIntegration.php ├── AllTestsRunner.php ├── AllTestsSelenium.php ├── AllTestsUnit.php ├── CHANGELOG.md ├── CONTRIBUTING.md ├── LICENSE ├── README.rst ├── additional.inc.php ├── base.php ├── bin ├── reset-shop ├── runmetrics ├── runtests ├── runtests-coverage └── runtests-selenium ├── bootstrap.php ├── composer.json ├── library ├── AcceptanceTestCase.php ├── BaseTestCase.php ├── Bootstrap │ ├── BootstrapBase.php │ ├── SeleniumBootstrap.php │ └── UnitBootstrap.php ├── Curl.php ├── Deprecated.php ├── FileCopier.php ├── Helper │ ├── ProjectConfigurationHelper.php │ ├── ProjectConfigurationHelperInterface.php │ ├── SessionHelper.php │ └── TestResultsPrintingHelper.php ├── MC_Metrics.php ├── MinkWrapper.php ├── MockStubFunc.php ├── ModuleLoader.php ├── ObjectValidator.php ├── Printer.php ├── RetryTestException.php ├── ServiceCaller.php ├── Services │ ├── ClearCache │ │ └── ClearCache.php │ ├── Files │ │ ├── ChangeExceptionLogRights.php │ │ └── Remove.php │ ├── Library │ │ ├── Cache.php │ │ ├── CliExecutor.php │ │ ├── DatabaseDefaultsFileGenerator.php │ │ ├── DatabaseHandler.php │ │ ├── DatabaseRestorer │ │ │ ├── DatabaseRestorer.php │ │ │ ├── DatabaseRestorerFactory.php │ │ │ ├── DatabaseRestorerInterface.php │ │ │ ├── DatabaseRestorerLocal.php │ │ │ └── DatabaseRestorerToFile.php │ │ ├── Exception │ │ │ └── FileNotFoundException.php │ │ ├── FileHandler.php │ │ ├── FileUploader.php │ │ ├── ProjectConfigurationHandler.php │ │ ├── Request.php │ │ ├── ServiceConfig.php │ │ └── ShopServiceInterface.php │ ├── ModuleInstaller │ │ └── ModuleInstaller.php │ ├── ServiceFactory.php │ ├── ShopInstaller │ │ └── ShopInstaller.php │ ├── ShopObjectConstructor │ │ ├── Constructor │ │ │ ├── ConstructorFactory.php │ │ │ ├── ObjectConstructor.php │ │ │ ├── oxBaseConstructor.php │ │ │ ├── oxConfigConstructor.php │ │ │ └── oxListConstructor.php │ │ └── ShopObjectConstructor.php │ ├── ShopPreparation │ │ └── ShopPreparation.php │ ├── SubShopHandler │ │ └── SubShopHandler.php │ ├── ThemeSwitcher │ │ └── ThemeSwitcher.php │ ├── ViewsGenerator │ │ └── ViewsGenerator.php │ └── service.php ├── ShopStateBackup.php ├── TestConfig.php ├── TestSqlPathProvider.php ├── Translator.php ├── UnitTestCase.php ├── VfsStreamWrapper.php ├── _cc.php └── helpers │ ├── ExceptionLogFileHelper.php │ ├── modOxUtilsDate.php │ ├── oxAdminViewHelper.php │ ├── oxArticleHelper.php │ ├── oxBaseHelper.php │ ├── oxBasketHelper.php │ ├── oxCacheHelper.php │ ├── oxCategoryHelper.php │ ├── oxDatabaseHelper.php │ ├── oxDeliveryHelper.php │ ├── oxEmailHelper.php │ ├── oxManufacturerHelper.php │ ├── oxNewsSubscribedHelper.php │ ├── oxSeoEncoderHelper.php │ ├── oxTestCacheConnector.php │ ├── oxUBaseHelper.php │ ├── oxUtilsFileHelper.php │ ├── oxUtilsHelper.php │ ├── oxVendorHelper.php │ └── oxVoucherHelper.php ├── phpunit.xml ├── test_config.yml.dist ├── tests ├── Integration │ ├── Services │ │ ├── Files │ │ │ ├── ChangeExceptionLogRightsTest.php │ │ │ ├── FilesHelper.php │ │ │ └── RemoveTest.php │ │ ├── Library │ │ │ ├── DatabaseDefaultsFileGeneratorTest.php │ │ │ └── ProjectConfigurationHandlerTest.php │ │ └── ShopInstaller │ │ │ └── ShopInstallerTest.php │ ├── UnitTestCaseTest.php │ └── helpers │ │ └── ExceptionLogFileHelperTest.php ├── bootstrap.php ├── phpunit.xml └── unit │ ├── FileCopierTest.php │ ├── Services │ ├── Library │ │ └── ServiceConfigTest.php │ └── ServiceFactoryTest.php │ ├── TestConfigTest.php │ ├── TestSqlPathProviderTest.php │ ├── UnitTestCaseTest.php │ └── VfsStreamWrapperTest.php └── workflow.puml /.gitignore: -------------------------------------------------------------------------------- 1 | # Composer 2 | composer.lock 3 | vendor/ 4 | 5 | # Testing library 6 | test_config.yml 7 | 8 | # IDE 9 | .idea 10 | -------------------------------------------------------------------------------- /AllTestsIntegration.php: -------------------------------------------------------------------------------- 1 | write( "Adding unit tests from $sDirectory\n"); 58 | 59 | $aTestFiles = array_diff($aTestFiles, static::$priorityTests); 60 | $oSuite = static::_addFilesToSuite($oSuite, $aTestFiles); 61 | } 62 | 63 | return $oSuite; 64 | } 65 | 66 | /** 67 | * Adds tests with highest priority. 68 | * 69 | * @param TestSuite $oSuite 70 | * @param array $aPriorityTests 71 | * @param array $aTestDirectories 72 | */ 73 | public static function _addPriorityTests($oSuite, $aPriorityTests, $aTestDirectories) 74 | { 75 | if (!empty($aPriorityTests)) { 76 | $aTestsToInclude = array(); 77 | foreach ($aPriorityTests as $sTestFile) { 78 | $sFolder = dirname($sTestFile); 79 | $aDirectories = array_filter($aTestDirectories, function($sTestDirectory) use ($sFolder){ 80 | return (substr($sTestDirectory, -strlen($sFolder)) === $sFolder); 81 | }); 82 | if (!empty($aDirectories)) { 83 | $fullPath = array_shift($aDirectories) .'/'. basename($sTestFile); 84 | if (file_exists($fullPath)) { 85 | $aTestsToInclude[] = $fullPath; 86 | } 87 | } 88 | } 89 | static::_addFilesToSuite($oSuite, $aTestsToInclude); 90 | } 91 | } 92 | 93 | /** 94 | * Returns array of directories, which should be tested 95 | * 96 | * @return array 97 | */ 98 | protected static function _getTestDirectories() 99 | { 100 | $aTestDirectories = array(); 101 | $aTestSuites = getenv('TEST_DIRS')? explode(',', getenv('TEST_DIRS')) : static::$testSuites; 102 | 103 | $testConfig = static::getTestConfig(); 104 | foreach ($aTestSuites as $sSuite) { 105 | $aTestDirectories[] = $testConfig->getCurrentTestSuite() ."/$sSuite"; 106 | } 107 | 108 | return array_merge($aTestDirectories, static::_getDirectoryTree($aTestDirectories)); 109 | } 110 | 111 | /** 112 | * Scans given tests directories and returns formed directory tree 113 | * 114 | * @param array $aDirectories 115 | * 116 | * @return array 117 | */ 118 | protected static function _getDirectoryTree($aDirectories) 119 | { 120 | $aTree = array(); 121 | 122 | foreach ($aDirectories as $sDirectory) { 123 | $aTree = array_merge($aTree, array_diff(glob($sDirectory . "/*", GLOB_ONLYDIR), array('.', '..'))); 124 | } 125 | 126 | if (!empty($aTree)) { 127 | $aTree = array_merge($aTree, static::_getDirectoryTree($aTree)); 128 | } 129 | 130 | return $aTree; 131 | } 132 | 133 | /** 134 | * Adds files to test suite 135 | * 136 | * @param TestSuite $oSuite 137 | * @param array $aTestFiles 138 | * 139 | * @return TestSuite 140 | */ 141 | protected static function _addFilesToSuite($oSuite, $aTestFiles) 142 | { 143 | foreach ($aTestFiles as $sFilename) { 144 | $sFilter = getenv('PREG_FILTER'); 145 | if (!$sFilter || preg_match("&$sFilter&i", $sFilename)) { 146 | $loweredFilename = strtolower($sFilename); 147 | if (!in_array($loweredFilename, self::$testFiles)) { 148 | $oSuite->addTestFile($sFilename); 149 | self::$testFiles[] = $loweredFilename; 150 | } 151 | } 152 | } 153 | 154 | return $oSuite; 155 | } 156 | 157 | /** 158 | * Returns Test configuration. 159 | * 160 | * @return OxidEsales\TestingLibrary\TestConfig 161 | */ 162 | protected static function getTestConfig() 163 | { 164 | if (is_null(static::$testConfig)) { 165 | static::$testConfig = new OxidEsales\TestingLibrary\TestConfig(); 166 | } 167 | 168 | return static::$testConfig; 169 | } 170 | } 171 | -------------------------------------------------------------------------------- /AllTestsSelenium.php: -------------------------------------------------------------------------------- 1 | sign the Contributor License Agreement. 4 | You can find more information about it on the FAQ page OXID Contribution and Contributor Agreement FAQ: 5 | https://docs.oxid-esales.com/developer/en/latest/development/modules_components_themes/contribution.html 6 | 7 | First off, you have to fork current repository. 8 | 9 | Best practice: 10 | * Please leave the the branch names as they are. 11 | * If you want to fix a bug or develop a new feature, define an own branch in your repository. Name it e.g. "feature/foo" or "bug/bugname" for better traceability. 12 | * Change whatever you want and send a pull request back to the original branch. 13 | 14 | For more information about this, please see:
15 | http://codeinthehole.com/writing/pull-requests-and-other-good-practices-for-teams-using-github/ 16 | 17 | You will find technical help with Git and GitHub on this place:
18 | https://help.github.com/ 19 | 20 | When sending your pull request, please provide a clear, meaningful and detailed information about what your code is about and what it will do, best including a screen shot if possible. 21 | -------------------------------------------------------------------------------- /additional.inc.php: -------------------------------------------------------------------------------- 1 | setParameter('serial', $testConfig->getShopSerial()); 22 | $serviceCaller->setParameter('addDemoData', 1); 23 | $serviceCaller->setParameter('turnOnVarnish', $testConfig->shouldEnableVarnish()); 24 | $serviceCaller->setParameter('setupPath', $testConfig->getShopSetupPath()); 25 | $serviceCaller->callService('ShopInstaller'); 26 | 27 | $container = ContainerFactory::getInstance()->getContainer(); 28 | $container->get(ConfigurationResettingServiceInterface::class)->reset(); 29 | -------------------------------------------------------------------------------- /bin/runmetrics: -------------------------------------------------------------------------------- 1 | #!/usr/bin/php 2 | getVendorDirectory() ."/bin/pdepend"; 27 | if (!file_exists($pDepend)) { 28 | $pDepend = "pdepend"; 29 | } 30 | $pDepend = "$php $pDepend"; 31 | 32 | $mcMetrics = "$php ". TEST_LIBRARY_PATH ."MC_Metrics.php"; 33 | 34 | $testSuites = $testConfig->getTestSuites(); 35 | foreach ($testSuites as $suite) { 36 | $reportsDir = $suite .'/reports'; 37 | $fileCopier->createEmptyDirectory($reportsDir); 38 | 39 | passthru("$pDepend --summary-xml=$reportsDir/pdepend.xml $ignore $arguments $suite/../"); 40 | passthru("$mcMetrics $reportsDir/pdepend.xml > $reportsDir/metrics.txt"); 41 | } 42 | -------------------------------------------------------------------------------- /bin/runtests: -------------------------------------------------------------------------------- 1 | #!/usr/bin/php 2 | getVendorDirectory() . "/bin/phpunit"; 31 | if (!file_exists($phpUnit)) { 32 | $phpUnit = "phpunit"; 33 | } 34 | $phpUnit = "$php $phpUnit --bootstrap " . __DIR__ . "/../bootstrap.php"; 35 | 36 | $arguments = empty($arguments) ? array(escapeshellarg('AllTestsUnit')) : $arguments; 37 | 38 | //print PHP version information 39 | $printer = new \OxidEsales\TestingLibrary\Printer(); 40 | $printer->write("=========\nrunning php version " . phpversion() . "\n\n============\n"); 41 | 42 | $returnCode = 0; 43 | /** Replace markers (e.g. /logs/phpunit_log_TIMESTAMP.xml) with unique timestamp strings */ 44 | $argumentString = $resultsHelper->insertReportTimestamps(implode(' ', $arguments)); 45 | if (end($arguments) == escapeshellarg('AllTestsUnit')) { 46 | $testSuites = $testConfig->getTestSuites(); 47 | if (!count($testSuites)){ 48 | $printer->write("ERROR: No test suites found!\n"); 49 | $returnCode = 78; //78 because it is sysexits default for configuration error 50 | } 51 | 52 | foreach ($testSuites as $suite) { 53 | $suiteReturnCode = runSuite($suite, $phpUnit, $argumentString); 54 | $returnCode = $returnCode == 0 ? $suiteReturnCode : $returnCode; 55 | } 56 | } else { 57 | $suite = $testConfig->getCurrentTestSuite(); 58 | $returnCode = runSuite($suite, $phpUnit, $argumentString); 59 | } 60 | 61 | exit($returnCode); 62 | 63 | function runSuite(string $suite, string $phpUnit, string $arguments) 64 | { 65 | $return = 0; 66 | $configuration = ''; 67 | if (file_exists($suite . "/phpunit.xml")) { 68 | $configuration = "-c " . escapeshellarg("$suite/phpunit.xml"); 69 | } 70 | $suite = escapeshellarg($suite); 71 | if (strpos($arguments, "'AllTestsUnit'") !== false) { 72 | $arguments = str_replace('AllTestsUnit', __DIR__."/../AllTestsUnit.php", $arguments); 73 | } 74 | passthru( 75 | "TEST_SUITE=$suite $phpUnit $configuration $arguments", 76 | $return 77 | ); 78 | return $return; 79 | } 80 | -------------------------------------------------------------------------------- /bin/runtests-coverage: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/OXID-eSales/testing_library/bd0d482adbca23391e020594944874e7efcd7e13/bin/runtests-coverage -------------------------------------------------------------------------------- /bin/runtests-selenium: -------------------------------------------------------------------------------- 1 | #!/usr/bin/php 2 | getVendorDirectory() . "/bin/phpunit"; 26 | if (!file_exists($phpUnit)) { 27 | $phpUnit = "phpunit"; 28 | } 29 | $phpUnit = "$php $phpUnit --bootstrap " . __DIR__ . "/../bootstrap.php"; 30 | 31 | $arguments = empty($arguments) ? array(escapeshellarg('AllTestsSelenium')) : $arguments; 32 | 33 | $returnCode = 0; 34 | /** Replace markers (e.g. /logs/phpunit_log_TIMESTAMP.xml) with unique timestamp strings */ 35 | $argumentString = $resultsHelper->insertReportTimestamps(implode(' ', $arguments)); 36 | if (end($arguments) == escapeshellarg('AllTestsSelenium')) { 37 | $testSuites = $testConfig->getTestSuites(); 38 | foreach ($testSuites as $suite) { 39 | $suiteReturnCode = runSuite($suite, $phpUnit, $argumentString); 40 | $returnCode = $returnCode == 0 ? $suiteReturnCode : $returnCode; 41 | } 42 | } else { 43 | $suite = $testConfig->getCurrentTestSuite(); 44 | $returnCode = runSuite($suite, $phpUnit, $argumentString); 45 | } 46 | 47 | exit($returnCode); 48 | 49 | function runSuite(string $suite, string $phpUnit, string $arguments) 50 | { 51 | $return = 0; 52 | $configuration = ''; 53 | if (file_exists($suite . "/phpunit.xml")) { 54 | $configuration = "-c " . escapeshellarg("$suite/phpunit.xml"); 55 | } 56 | $suite = escapeshellarg($suite); 57 | if (strpos($arguments, "'AllTestsSelenium'") !== false) { 58 | $arguments = str_replace('AllTestsSelenium', __DIR__."/../AllTestsSelenium.php", $arguments); 59 | } 60 | passthru( 61 | "TEST_SUITE=$suite $phpUnit $configuration $arguments", 62 | $return 63 | ); 64 | return $return; 65 | } 66 | -------------------------------------------------------------------------------- /bootstrap.php: -------------------------------------------------------------------------------- 1 | init(); 34 | -------------------------------------------------------------------------------- /composer.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "oxid-esales/testing-library", 3 | "description": "OXID eShop testing library", 4 | "license": "proprietary", 5 | "type": "library", 6 | "keywords": [ 7 | "oxid", 8 | "testing", 9 | "library", 10 | "modules", 11 | "eShop" 12 | ], 13 | "homepage": "https://www.oxid-esales.com/en/home.html", 14 | "require": { 15 | "php": "^8.0", 16 | "behat/mink": "^1.5.0", 17 | "incenteev/composer-parameter-handler": "^2.1.4", 18 | "mikey179/vfsstream": "^1.6.8", 19 | "oxid-esales/developer-tools": "*", 20 | "oxid-esales/mink-selenium-driver": "dev-b-8.0.x", 21 | "oxid-esales/oxideshop-facts": "*", 22 | "oxid-esales/oxideshop-unified-namespace-generator": "*", 23 | "pdepend/pdepend": "^2.7", 24 | "phpspec/prophecy-phpunit": "^v2.0.1", 25 | "phpunit/php-code-coverage": "^9", 26 | "phpunit/phpcov": "^8", 27 | "phpunit/phpunit": "^9.1.1", 28 | "symfony/filesystem": "*", 29 | "symfony/process": "*", 30 | "symfony/yaml": "*" 31 | }, 32 | "minimum-stability": "dev", 33 | "prefer-stable": true, 34 | "autoload": { 35 | "psr-4": { 36 | "OxidEsales\\TestingLibrary\\": "library/" 37 | } 38 | }, 39 | "autoload-dev": { 40 | "psr-4": { 41 | "OxidEsales\\TestingLibrary\\Tests\\": "./tests" 42 | } 43 | }, 44 | "include-path": [ 45 | "../../symfony/yaml/" 46 | ], 47 | "bin": [ 48 | "bin/reset-shop", 49 | "bin/runmetrics", 50 | "bin/runtests", 51 | "bin/runtests-coverage", 52 | "bin/runtests-selenium" 53 | ], 54 | "extra": { 55 | "incenteev-parameters": { 56 | "env-map": { 57 | "module_ids": "MODULE_IDS", 58 | "shop_path": "SHOP_PATH", 59 | "shop_tests_path": "SHOP_TESTS_PATH" 60 | }, 61 | "file": "test_config.yml", 62 | "parameter-key": "mandatory_parameters" 63 | } 64 | }, 65 | "scripts": { 66 | "post-install-cmd": [ 67 | "Incenteev\\ParameterHandler\\ScriptHandler::buildParameters" 68 | ], 69 | "post-update-cmd": [ 70 | "Incenteev\\ParameterHandler\\ScriptHandler::buildParameters" 71 | ] 72 | } 73 | } 74 | -------------------------------------------------------------------------------- /library/BaseTestCase.php: -------------------------------------------------------------------------------- 1 | exceptionLogHelper = new \OxidEsales\TestingLibrary\helpers\ExceptionLogFileHelper(OX_LOG_FILE); 36 | } 37 | 38 | /** 39 | * Returns test configuration. 40 | * 41 | * @return TestConfig 42 | */ 43 | public static function getStaticTestConfig() 44 | { 45 | if (is_null(self::$testConfig)) { 46 | self::$testConfig = new TestConfig(); 47 | } 48 | 49 | return self::$testConfig; 50 | } 51 | 52 | /** 53 | * Returns test configuration. 54 | * 55 | * @return TestConfig 56 | */ 57 | public function getTestConfig() 58 | { 59 | return self::getStaticTestConfig(); 60 | } 61 | 62 | /** 63 | * Mark the test as skipped until given date. 64 | * Wrapper function for PHPUnit\Framework\Assert::markTestSkipped. 65 | * 66 | * @param string $sDate Date string in format 'Y-m-d'. 67 | * @param string $sMessage Message. 68 | * 69 | * @throws SkippedTestError 70 | */ 71 | public function markTestSkippedUntil($sDate, $sMessage = '') 72 | { 73 | $oDate = DateTime::createFromFormat('Y-m-d', $sDate); 74 | 75 | if (time() < ((int) $oDate->format('U'))) { 76 | $this->markTestSkipped($sMessage); 77 | } 78 | } 79 | 80 | /** 81 | * Activates the theme for running acceptance tests on. 82 | * 83 | * @todo Refactor this method to use ThemeSwitcher service. This will require a prior refactoring of the testing library. 84 | * 85 | * @param string $themeName Name of the theme to activate 86 | * 87 | * @throws \OxidEsales\Eshop\Core\Exception\SystemComponentException 88 | */ 89 | public function activateTheme($themeName) 90 | { 91 | $currentShopId = \OxidEsales\Eshop\Core\Registry::getConfig()->getShopId(); 92 | 93 | $theme = oxNew(\OxidEsales\Eshop\Core\Theme::class); 94 | $theme->load($themeName); 95 | 96 | $testConfig = new TestConfig(); 97 | $shopId = $testConfig->getShopId(); 98 | \OxidEsales\Eshop\Core\Registry::getConfig()->setShopId($shopId); 99 | 100 | $theme->activate(); 101 | 102 | /** 103 | * In the tests, the main shops' theme always hay to be switched too. 104 | * If the current shop is not a parent shop (i.e. shopId == 1), activate the theme in the parent shop as well. 105 | */ 106 | if ($shopId != 1) { 107 | \OxidEsales\Eshop\Core\Registry::getConfig()->setShopId(1); 108 | 109 | $theme->activate(); 110 | } 111 | 112 | \OxidEsales\Eshop\Core\Registry::getConfig()->setShopId($currentShopId); 113 | } 114 | 115 | /** 116 | * @throws \OxidEsales\Eshop\Core\Exception\StandardException 117 | */ 118 | protected function setUp(): void 119 | { 120 | parent::setUp(); 121 | $this->failOnLoggedExceptions(); 122 | } 123 | 124 | /** 125 | * @throws \OxidEsales\Eshop\Core\Exception\StandardException 126 | */ 127 | protected function tearDown(): void 128 | { 129 | parent::tearDown(); 130 | $this->failOnLoggedExceptions(); 131 | } 132 | 133 | /** 134 | * @param string $expectedExceptionClass 135 | * @param string $expectedExceptionMessage 136 | * 137 | * @throws \OxidEsales\Eshop\Core\Exception\StandardException 138 | */ 139 | protected function assertLoggedException($expectedExceptionClass, $expectedExceptionMessage = '') 140 | { 141 | $this->assertCount( 142 | 1, 143 | $this->exceptionLogHelper->getParsedExceptions() 144 | ); 145 | 146 | $this->assertStringContainsString( 147 | $expectedExceptionClass, 148 | $this->exceptionLogHelper->getParsedExceptions()[0] 149 | ); 150 | 151 | if ($expectedExceptionMessage) { 152 | $this->assertStringContainsString( 153 | $expectedExceptionMessage, 154 | $this->exceptionLogHelper->getParsedExceptions()[0] 155 | ); 156 | } 157 | 158 | $this->exceptionLogHelper->clearExceptionLogFile(); 159 | } 160 | 161 | /** 162 | * @throws \OxidEsales\Eshop\Core\Exception\StandardException 163 | */ 164 | protected function failOnLoggedExceptions() 165 | { 166 | if ($exceptionLogEntries = $this->exceptionLogHelper->getExceptionLogFileContent()) { 167 | $this->exceptionLogHelper->clearExceptionLogFile(); 168 | $this->fail('Test failed with ' . OX_LOG_FILE . ' entry:' . $exceptionLogEntries); 169 | } 170 | } 171 | } -------------------------------------------------------------------------------- /library/Bootstrap/BootstrapBase.php: -------------------------------------------------------------------------------- 1 | testConfig = new TestConfig(); 28 | } 29 | 30 | /** 31 | * Prepares tests environment. 32 | */ 33 | public function init() 34 | { 35 | $testConfig = $this->getTestConfig(); 36 | 37 | $this->cleanUpExceptionLogFile(); 38 | $this->prepareShop(); 39 | $this->setGlobalConstants(); 40 | 41 | if ($testConfig->shouldRestoreShopAfterTestsSuite()) { 42 | $this->registerResetDbAfterSuite(); 43 | } 44 | 45 | if ($testConfig->shouldInstallShop()) { 46 | $this->installShop(); 47 | } 48 | 49 | /** @var \OxidEsales\Eshop\Core\Config $config */ 50 | $config = oxNew(\OxidEsales\Eshop\Core\Config::class); 51 | \OxidEsales\Eshop\Core\Registry::set(\OxidEsales\Eshop\Core\Config::class, $config); 52 | 53 | $config->init(); 54 | } 55 | 56 | /** 57 | * Returns tests config. 58 | * 59 | * @return TestConfig 60 | */ 61 | public function getTestConfig() 62 | { 63 | return $this->testConfig; 64 | } 65 | 66 | /** 67 | * Prepares shop config object. 68 | */ 69 | protected function prepareShop() 70 | { 71 | $testConfig = $this->getTestConfig(); 72 | 73 | $shopPath = $testConfig->getShopPath(); 74 | require_once $shopPath .'bootstrap.php'; 75 | 76 | $tempDirectory = $testConfig->getTempDirectory(); 77 | if ($tempDirectory && $tempDirectory != '/') { 78 | $fileCopier = new FileCopier(); 79 | $fileCopier->createEmptyDirectory($tempDirectory); 80 | } 81 | } 82 | 83 | /** 84 | * Sets global constants, as these are still used a lot in tests. 85 | * This is used to maintain backwards compatibility, but should not be used anymore in new code. 86 | */ 87 | protected function setGlobalConstants() 88 | { 89 | $testConfig = $this->getTestConfig(); 90 | 91 | if (!defined('oxPATH')) { 92 | /** @deprecated use TestConfig::getShopPath() */ 93 | define('oxPATH', $testConfig->getShopPath()); 94 | } 95 | 96 | if (!defined('CURRENT_TEST_SUITE')) { 97 | /** @deprecated use TestConfig::getCurrentTestSuite() */ 98 | define('CURRENT_TEST_SUITE', $testConfig->getCurrentTestSuite()); 99 | } 100 | } 101 | 102 | /** 103 | * Installs the shop. 104 | * 105 | * @throws \Exception 106 | */ 107 | protected function installShop() 108 | { 109 | $config = $this->getTestConfig(); 110 | 111 | $serviceCaller = new ServiceCaller($this->getTestConfig()); 112 | $serviceCaller->setParameter('serial', $config->getShopSerial()); 113 | $serviceCaller->setParameter('addDemoData', $this->addDemoData); 114 | $serviceCaller->setParameter('turnOnVarnish', $config->shouldEnableVarnish()); 115 | 116 | if ($setupPath = $config->getShopSetupPath()) { 117 | $fileCopier = new FileCopier(); 118 | $remoteDirectory = $config->getRemoteDirectory(); 119 | $shopDirectory = $remoteDirectory ? $remoteDirectory : $config->getShopPath(); 120 | $fileCopier->copyFiles($setupPath, $shopDirectory.'/Setup/'); 121 | } 122 | 123 | try { 124 | $serviceCaller->callService('ShopInstaller'); 125 | } catch (\Exception $e) { 126 | exit("Failed to install shop with message: " . $e->getMessage() . PHP_EOL . $e->getTraceAsString()); 127 | } 128 | } 129 | 130 | /** 131 | * Creates original database dump and registers database restoration 132 | * after the tests suite. 133 | */ 134 | protected function registerResetDbAfterSuite() 135 | { 136 | $serviceCaller = new ServiceCaller($this->getTestConfig()); 137 | $serviceCaller->setParameter('dumpDB', true); 138 | $serviceCaller->setParameter('dump-prefix', 'orig_db_dump'); 139 | try { 140 | $serviceCaller->callService('ShopPreparation', 1); 141 | } catch (\Exception $e) { 142 | define('RESTORE_SHOP_AFTER_TEST_SUITE_ERROR', true); 143 | } 144 | 145 | register_shutdown_function(function () { 146 | if (!defined('RESTORE_SHOP_AFTER_TEST_SUITE_ERROR')) { 147 | $serviceCaller = new ServiceCaller(); 148 | $serviceCaller->setParameter('restoreDB', true); 149 | $serviceCaller->setParameter('dump-prefix', 'orig_db_dump'); 150 | $serviceCaller->callService('ShopPreparation', 1); 151 | } 152 | }); 153 | } 154 | 155 | /** 156 | * Cleans exception log. 157 | */ 158 | private function cleanUpExceptionLogFile() 159 | { 160 | $exceptionLogHelper = $this->getExceptionLogHelper(); 161 | $exceptionLogHelper->clearExceptionLogFile(); 162 | } 163 | 164 | /** 165 | * Returns ExceptionLogFileHelper. 166 | * 167 | * @return ExceptionLogFileHelper 168 | */ 169 | private function getExceptionLogHelper() 170 | { 171 | $exceptionLogPath = $this->testConfig->getShopPath() . '/log/oxideshop.log'; 172 | 173 | return new ExceptionLogFileHelper($exceptionLogPath); 174 | } 175 | } 176 | -------------------------------------------------------------------------------- /library/Bootstrap/SeleniumBootstrap.php: -------------------------------------------------------------------------------- 1 | getTestConfig()->getShopEdition() == 'EE') ? 'EE' : 'PE_CE'); 25 | 26 | $this->prepareScreenShots(); 27 | $this->copyTestFilesToShop(); 28 | 29 | /** @var \OxidEsales\Eshop\Core\Config $config */ 30 | $config = oxNew(\OxidEsales\Eshop\Core\Config::class); 31 | \OxidEsales\Eshop\Core\Registry::set(\OxidEsales\Eshop\Core\Config::class, $config); 32 | 33 | register_shutdown_function(function () { 34 | AcceptanceTestCase::stopMinkSession(); 35 | }); 36 | } 37 | 38 | /** 39 | * Creates screenshots directory if it does not exists. 40 | */ 41 | public function prepareScreenShots() 42 | { 43 | $screenShotsPath = $this->getTestConfig()->getScreenShotsPath(); 44 | if ($screenShotsPath && !is_dir($screenShotsPath)) { 45 | mkdir($screenShotsPath, 0777, true); 46 | } 47 | } 48 | 49 | /** 50 | * Sets global constants, as these are still used a lot in tests. 51 | * This is used to maintain backwards compatibility, but should not be used anymore in new code. 52 | */ 53 | protected function setGlobalConstants() 54 | { 55 | parent::setGlobalConstants(); 56 | $testConfig = $this->getTestConfig(); 57 | 58 | /** @deprecated use TestConfig::getShopUrl() */ 59 | define('shopURL', $testConfig->getShopUrl()); 60 | 61 | /** @deprecated use TestConfig::getShopId() */ 62 | define('oxSHOPID', $testConfig->getShopId()); 63 | 64 | /** @deprecated use TestConfig::isSubShop() */ 65 | define('isSUBSHOP', $testConfig->isSubShop()); 66 | } 67 | 68 | /** 69 | * Some test files are needed to successfully run selenium tests. 70 | * Currently only files needed for clearing cookies are copied. 71 | */ 72 | public function copyTestFilesToShop() 73 | { 74 | $config = $this->getTestConfig(); 75 | $target = $config->getRemoteDirectory() ? $config->getRemoteDirectory().'/_cc.php' : $config->getShopPath().'/_cc.php'; 76 | $fileCopier = new FileCopier(); 77 | $fileCopier->copyFiles(TEST_LIBRARY_PATH .'_cc.php', $target, true); 78 | } 79 | } 80 | -------------------------------------------------------------------------------- /library/Bootstrap/UnitBootstrap.php: -------------------------------------------------------------------------------- 1 | initializeConfig(); 22 | 23 | error_reporting(E_ALL & ~E_DEPRECATED & ~E_NOTICE & ~E_WARNING); 24 | 25 | $currentTestSuite = $this->getTestConfig()->getCurrentTestSuite(); 26 | if (file_exists($currentTestSuite .'/additional.inc.php')) { 27 | include_once $currentTestSuite .'/additional.inc.php'; 28 | // There is a need to reinitialize config, otherwise configs from SQL file which can be imported via 29 | // additional.inc.php will not be taken. 30 | $this->initializeConfig(); 31 | } 32 | 33 | define('TEST_PREPARATION_FINISHED', true); 34 | } 35 | 36 | /** 37 | * Prepare shop configuration. Force UTF8 mode, compile directory and database name to be used during testing. 38 | */ 39 | public function prepareShop() 40 | { 41 | parent::prepareShop(); 42 | 43 | $shopConfig = \OxidEsales\Eshop\Core\Registry::get(\OxidEsales\Eshop\Core\ConfigFile::class); 44 | if ($testDatabase = $this->getTestConfig()->getTestDatabaseName()) { 45 | $shopConfig->setVar('dbName', $testDatabase); 46 | } 47 | } 48 | 49 | /** 50 | * Forces configuration values from oxConfigFile object to oxConfig. 51 | */ 52 | public function initializeConfig() 53 | { 54 | $config = \OxidEsales\Eshop\Core\Registry::getConfig(); 55 | $configFile = \OxidEsales\Eshop\Core\Registry::get(\OxidEsales\Eshop\Core\ConfigFile::class); 56 | $config->reinitialize(); 57 | $config->setConfigParam('dbName', $configFile->getVar('dbName')); 58 | } 59 | } 60 | } 61 | 62 | namespace { 63 | 64 | /** 65 | * @deprecated Use TestConfig::getCurrentTestSuite() or TestConfig::getTempDirectory(). 66 | * 67 | * @return string 68 | */ 69 | function getTestsBasePath() 70 | { 71 | $testsPath = ''; 72 | if (defined('CURRENT_TEST_SUITE')) { 73 | $testsPath = CURRENT_TEST_SUITE; 74 | } 75 | return $testsPath; 76 | } 77 | 78 | /** 79 | * Returns framework base path. 80 | * Overwrites original method so that it would be possible to mock shop directory during testing. 81 | * 82 | * @return string 83 | */ 84 | function getShopBasePath() 85 | { 86 | $shopDirectory = null; 87 | if (defined('TEST_PREPARATION_FINISHED')) { 88 | $config = \OxidEsales\Eshop\Core\Registry::getConfig(); 89 | $shopDirectory = $config->getConfigParam('sShopDir'); 90 | } 91 | return rtrim($shopDirectory ?: OX_BASE_PATH, DIRECTORY_SEPARATOR) . DIRECTORY_SEPARATOR; 92 | } 93 | } 94 | -------------------------------------------------------------------------------- /library/FileCopier.php: -------------------------------------------------------------------------------- 1 | executeCommand($command); 41 | } 42 | 43 | /** 44 | * Creates new directory if it does not exists, if exists - clears its content. 45 | * 46 | * @param string $directory 47 | */ 48 | public function createEmptyDirectory($directory) 49 | { 50 | if (!is_dir($directory)) { 51 | mkdir($directory, 0777, true); 52 | } else { 53 | $this->deleteTree($directory, false); 54 | } 55 | } 56 | 57 | /** 58 | * Deletes given directory content 59 | * 60 | * @param string $directory Path to directory. 61 | * @param bool $removeBaseDir Whether to delete base directory. 62 | */ 63 | protected function deleteTree($directory, $removeBaseDir = false) 64 | { 65 | $files = array_diff(scandir($directory), array('.', '..')); 66 | foreach ($files as $file) { 67 | (is_dir("$directory/$file")) ? $this->deleteTree("$directory/$file", true) : @unlink("$directory/$file"); 68 | } 69 | 70 | if ($removeBaseDir) { 71 | @rmdir($directory); 72 | } 73 | } 74 | 75 | /** 76 | * Executes shell command. 77 | * 78 | * @param string $command 79 | * 80 | * @throws Exception 81 | * 82 | * @return string Output of command. 83 | */ 84 | protected function executeCommand($command) 85 | { 86 | $result = @exec($command, $output, $code); 87 | $output = implode("\n", $output); 88 | 89 | if ($result === false) { 90 | throw new Exception("Failed to execute command '$command' with message: [$code] '$output'"); 91 | } 92 | 93 | return $output; 94 | } 95 | } 96 | -------------------------------------------------------------------------------- /library/Helper/ProjectConfigurationHelper.php: -------------------------------------------------------------------------------- 1 | getShopRootPath(), '/var/'); 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /library/Helper/ProjectConfigurationHelperInterface.php: -------------------------------------------------------------------------------- 1 | getUniqueTimestamp(), $extension); 20 | } 21 | 22 | public function insertReportTimestamps(string $command): string 23 | { 24 | return str_replace(self::TIMESTAMP_INSERTION_MARKER, $this->getUniqueTimestamp(), $command); 25 | } 26 | 27 | private function getUniqueTimestamp(): string 28 | { 29 | return sprintf('%s_%s', date(self::TIMESTAMP_FORMAT), uniqid()); 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /library/MockStubFunc.php: -------------------------------------------------------------------------------- 1 | _func = $sFunc; 27 | } 28 | 29 | /** 30 | * Fakes the processing of the invocation $invocation by returning a 31 | * specific value. 32 | * 33 | * @param Invocation $invocation 34 | * The invocation which was mocked and matched by the current method 35 | * and argument matchers. 36 | * 37 | * @return mixed 38 | */ 39 | public function invoke(Invocation $invocation) 40 | { 41 | if (is_string($this->_func) && preg_match('/^\{.+\}$/', $this->_func)) { 42 | $args = $invocation->getParameters(); 43 | $_this = $invocation->getObject(); 44 | 45 | return eval($this->_func); 46 | } else { 47 | return call_user_func_array($this->_func, $invocation->getParameters()); 48 | } 49 | } 50 | 51 | /** 52 | * Returns user called function. 53 | * 54 | * @return string 55 | */ 56 | public function toString(): string 57 | { 58 | return 'call user-specified function ' . $this->_func; 59 | } 60 | } 61 | -------------------------------------------------------------------------------- /library/ModuleLoader.php: -------------------------------------------------------------------------------- 1 | getContainer()->get(ModuleActivationBridgeInterface::class); 29 | $shopId = Registry::getConfig()->getShopId(); 30 | foreach ($modulesToActivate as $moduleId) { 31 | if (!$moduleActivationService->isActive($moduleId, $shopId)) { 32 | $this->activateModule($moduleId); 33 | Registry::getConfig()->reinitialize(); 34 | } 35 | } 36 | $this->makeModuleServicesAvailableInDIContainer(); 37 | } 38 | 39 | private function getContainer(): ContainerInterface 40 | { 41 | return ContainerFactory::getInstance()->getContainer(); 42 | } 43 | 44 | private function makeModuleServicesAvailableInDIContainer(): void 45 | { 46 | ContainerFactory::resetContainer(); 47 | } 48 | 49 | private function activateModule(string $moduleId): void 50 | { 51 | $rootPath = (new Facts())->getShopRootPath(); 52 | $process = new Process( 53 | [$this->getConsoleRunner($rootPath), 'oe:module:activate', $moduleId], 54 | $rootPath 55 | ); 56 | $process->mustRun(); 57 | } 58 | 59 | private function getConsoleRunner(string $rootPath): string 60 | { 61 | $possiblePaths = [ 62 | 'bin/oe-console', 63 | 'vendor/bin/oe-console', 64 | ]; 65 | foreach ($possiblePaths as $path) { 66 | if (is_file(Path::join($rootPath, $path))) { 67 | return $path; 68 | } 69 | } 70 | throw new RuntimeException('Could not find script "bin/oe-console" to activate module'); 71 | } 72 | } 73 | -------------------------------------------------------------------------------- /library/ObjectValidator.php: -------------------------------------------------------------------------------- 1 | _getObjectParameters($sClass, array_keys($aExpectedParams), $sOxId); 25 | 26 | $blResult = true; 27 | foreach ($aExpectedParams as $sKey => $sExpectedValue) { 28 | $sObjectValue = $aObjectParams[$sKey]; 29 | if ($sExpectedValue !== $sObjectValue) { 30 | $this->_setError("'$sExpectedValue' != '$sObjectValue' on key '$sKey'"); 31 | $blResult = false; 32 | } 33 | } 34 | 35 | return $blResult; 36 | } 37 | 38 | /** 39 | * Returns formed error message if parameters was not valid 40 | * 41 | * @return string 42 | */ 43 | public function getErrorMessage() 44 | { 45 | $sMessage = ''; 46 | $aErrors = $this->_getErrors(); 47 | if (!empty($aErrors)) { 48 | $sMessage = "Expected and actual parameters do not match: \n"; 49 | $sMessage .= implode("\n", $aErrors); 50 | } 51 | 52 | return $sMessage; 53 | } 54 | 55 | /** 56 | * Sets error message to error stack 57 | * 58 | * @param string $sMessage 59 | */ 60 | protected function _setError($sMessage) 61 | { 62 | $this->_aErrors[] = $sMessage; 63 | } 64 | 65 | /** 66 | * Returns errors array 67 | * 68 | * @return array 69 | */ 70 | protected function _getErrors() 71 | { 72 | return $this->_aErrors; 73 | } 74 | 75 | /** 76 | * Returns object parameters 77 | * 78 | * @param string $sClass 79 | * @param array $aObjectParams 80 | * @param string $sOxId 81 | * @param string $sShopId 82 | * 83 | * @return mixed 84 | */ 85 | protected function _getObjectParameters($sClass, $aObjectParams, $sOxId = null, $sShopId = null) 86 | { 87 | $oServiceCaller = new ServiceCaller(); 88 | $oServiceCaller->setParameter('cl', $sClass); 89 | 90 | $sOxId = $sOxId ? $sOxId : 'lastInsertedId'; 91 | $oServiceCaller->setParameter('oxid', $sOxId); 92 | $oServiceCaller->setParameter('classparams', $aObjectParams); 93 | 94 | return $oServiceCaller->callService('ShopObjectConstructor', $sShopId); 95 | } 96 | } 97 | -------------------------------------------------------------------------------- /library/Printer.php: -------------------------------------------------------------------------------- 1 | out) { 27 | \fwrite($this->out, $buffer); 28 | } else { 29 | if (PHP_SAPI != 'cli' && PHP_SAPI != 'phpdbg') { 30 | $buffer = \htmlspecialchars($buffer, ENT_SUBSTITUTE); 31 | } 32 | 33 | print $buffer; 34 | } 35 | } 36 | 37 | /** 38 | * @inheritdoc 39 | */ 40 | public function addError(Test $test, \Throwable $throwable, float $time): void 41 | { 42 | if ($this->verbose) { 43 | $this->write(" ERROR: '" . $throwable->getMessage() . "'\n" . $throwable->getTraceAsString()); 44 | } 45 | parent::addError($test, $throwable, $time); 46 | } 47 | 48 | /** 49 | * @inheritdoc 50 | */ 51 | public function addFailure(Test $test, AssertionFailedError $e, float $time): void 52 | { 53 | if ($this->verbose) { 54 | $this->write(" FAIL: '" . $e->getMessage() . "'\n" . $e->getTraceAsString()); 55 | } 56 | parent::addFailure($test, $e, $time); 57 | } 58 | 59 | /** 60 | * @inheritdoc 61 | */ 62 | public function endTest(Test $test, float $time): void 63 | { 64 | if ($this->verbose) { 65 | $t = microtime(true) - $this->timeStats['startTime']; 66 | if ($this->timeStats['min'] > $t) { 67 | $this->timeStats['min'] = $t; 68 | } 69 | if ($this->timeStats['max'] < $t) { 70 | $this->timeStats['max'] = $t; 71 | $this->timeStats['slowest'] = $test->getName(); 72 | } 73 | $this->timeStats['avg'] = ($t + $this->timeStats['avg'] * $this->timeStats['cnt']) / (++$this->timeStats['cnt']); 74 | } 75 | parent::endTest($test, $time); 76 | } 77 | 78 | /** 79 | * @inheritdoc 80 | */ 81 | public function endTestSuite(TestSuite $suite): void 82 | { 83 | parent::endTestSuite($suite); 84 | 85 | if ($this->verbose) { 86 | $this->write("\ntime stats: min {$this->timeStats['min']}, max {$this->timeStats['max']}, avg {$this->timeStats['avg']}, slowest test: {$this->timeStats['slowest']}|\n"); 87 | } 88 | } 89 | 90 | /** 91 | * @inheritdoc 92 | */ 93 | public function startTestSuite(TestSuite $suite): void 94 | { 95 | if ($this->verbose) { 96 | $this->write("\n\n" . $suite->getName() . "\n"); 97 | 98 | $this->timeStats = array('cnt' => 0, 'min' => 9999999, 'max' => 0, 'avg' => 0, 'startTime' => 0, 'slowest' => '_ERROR_'); 99 | } 100 | 101 | parent::startTestSuite($suite); 102 | } 103 | 104 | /** 105 | * @inheritdoc 106 | */ 107 | public function startTest(Test $test): void 108 | { 109 | if ($this->verbose) { 110 | $this->write("\n " . $test->getName()); 111 | 112 | $this->timeStats['startTime'] = microtime(true); 113 | } 114 | 115 | parent::startTest($test); 116 | } 117 | } 118 | -------------------------------------------------------------------------------- /library/RetryTestException.php: -------------------------------------------------------------------------------- 1 | config = $config; 39 | } 40 | 41 | /** 42 | * Sets given parameters. 43 | * 44 | * @param string $sKey Parameter name. 45 | * @param string $aVal Parameter value. 46 | */ 47 | public function setParameter($sKey, $aVal) 48 | { 49 | $this->parameters[$sKey] = $aVal; 50 | } 51 | 52 | /** 53 | * Returns array of parameters. 54 | * 55 | * @return array 56 | */ 57 | public function getParameters() 58 | { 59 | return $this->parameters; 60 | } 61 | 62 | /** 63 | * Call shop service to execute code in shop. 64 | * 65 | * @param string $serviceName 66 | * @param string $shopId 67 | * 68 | * @example call to update information to database. 69 | * 70 | * @throws \Exception 71 | * 72 | * @return string $sResult 73 | */ 74 | public function callService($serviceName, $shopId = null) 75 | { 76 | $testConfig = $this->getTestConfig(); 77 | if (!is_null($shopId) && $testConfig->getShopEdition() == 'EE') { 78 | $this->setParameter('shp', $shopId); 79 | } elseif ($testConfig->isSubShop()) { 80 | $this->setParameter('shp', $testConfig->getShopId()); 81 | } 82 | 83 | if ($testConfig->getRemoteDirectory()) { 84 | $response = $this->callRemoteService($serviceName); 85 | } else { 86 | $this->callLocalService(ChangeExceptionLogRights::class); 87 | 88 | $response = $this->callLocalService($serviceName); 89 | } 90 | 91 | $this->parameters = array(); 92 | 93 | return $response; 94 | } 95 | 96 | /** 97 | * Calls service on remote server. 98 | * 99 | * @param string $serviceName 100 | * 101 | * @throws \Exception 102 | * 103 | * @return string 104 | */ 105 | protected function callRemoteService($serviceName) 106 | { 107 | if (!self::$servicesCopied) { 108 | self::$servicesCopied = true; 109 | $this->copyServicesToShop(); 110 | } 111 | 112 | $oCurl = new Curl(); 113 | 114 | $this->setParameter('service', $serviceName); 115 | 116 | $oCurl->setUrl($this->getTestConfig()->getShopUrl() . '/Services/service.php'); 117 | $oCurl->setParameters($this->getParameters()); 118 | 119 | $sResponse = $oCurl->execute(); 120 | 121 | if ($oCurl->getStatusCode() >= 300) { 122 | $sResponse = $oCurl->execute(); 123 | } 124 | 125 | return $this->unserializeResponse($sResponse); 126 | } 127 | 128 | /** 129 | * Calls service on local server. 130 | * 131 | * @param string $serviceName 132 | * 133 | * @return mixed|null 134 | */ 135 | protected function callLocalService($serviceName) 136 | { 137 | if (!defined('TMP_PATH')) { 138 | define('TMP_PATH', $this->getTestConfig()->getTempDirectory()); 139 | } 140 | 141 | $config = new ServiceConfig($this->getTestConfig()->getShopPath(), $this->getTestConfig()->getTempDirectory()); 142 | $config->setShopEdition($this->getTestConfig()->getShopEdition()); 143 | 144 | $serviceCaller = new ServiceFactory($config); 145 | $request = new Request($this->getParameters()); 146 | $service = $serviceCaller->createService($serviceName); 147 | 148 | return $service->init($request); 149 | } 150 | 151 | /** 152 | * Returns tests config object. 153 | * 154 | * @return TestConfig 155 | */ 156 | protected function getTestConfig() 157 | { 158 | return $this->config; 159 | } 160 | 161 | /** 162 | * Copies services directory to shop. 163 | */ 164 | protected function copyServicesToShop() 165 | { 166 | $fileCopier = new FileCopier(); 167 | $target = $this->getTestConfig()->getRemoteDirectory() . '/Services'; 168 | $fileCopier->copyFiles(TEST_LIBRARY_PATH.'/Services', $target, true); 169 | } 170 | 171 | /** 172 | * Unserializes given string. Throws exception if incorrect string is passed 173 | * 174 | * @param string $response 175 | * 176 | * @throws \Exception 177 | * 178 | * @return mixed 179 | */ 180 | private function unserializeResponse($response) 181 | { 182 | $result = unserialize($response); 183 | if ($response !== 'b:0;' && $result === false) { 184 | throw new \Exception(substr($response, 0, 5000)); 185 | } 186 | 187 | return $result; 188 | } 189 | } 190 | -------------------------------------------------------------------------------- /library/Services/ClearCache/ClearCache.php: -------------------------------------------------------------------------------- 1 | serviceConfig = $config; 27 | } 28 | 29 | /** 30 | * Clears shop cache. 31 | * 32 | * @param Request $request 33 | */ 34 | public function init($request) 35 | { 36 | $cache = new Cache(); 37 | if ($this->getServiceConfig()->getShopEdition() === ServiceConfig::EDITION_ENTERPRISE) { 38 | $cache->clearCacheBackend(); 39 | if ($request->getParameter('clearVarnish')) { 40 | $cache->clearReverseProxyCache(); 41 | } 42 | } 43 | $cache->clearTemporaryDirectory(); 44 | } 45 | 46 | /** 47 | * @return ServiceConfig 48 | */ 49 | protected function getServiceConfig() 50 | { 51 | return $this->serviceConfig; 52 | } 53 | } 54 | -------------------------------------------------------------------------------- /library/Services/Files/ChangeExceptionLogRights.php: -------------------------------------------------------------------------------- 1 | serviceConfig = $config; 38 | $this->fileSystem = new Filesystem(); 39 | } 40 | 41 | /** 42 | * @param \OxidEsales\TestingLibrary\Services\Library\Request $request 43 | */ 44 | public function init($request) 45 | { 46 | $fileSystem = new Filesystem(); 47 | 48 | $pathToExceptionLog = $this->serviceConfig->getShopDirectory() 49 | . DIRECTORY_SEPARATOR . self::EXCEPTION_LOG_PATH; 50 | 51 | if (!$fileSystem->exists([$pathToExceptionLog])) { 52 | $fileSystem->touch($pathToExceptionLog); 53 | } 54 | $fileSystem->chmod($pathToExceptionLog, 0777); 55 | } 56 | } 57 | -------------------------------------------------------------------------------- /library/Services/Files/Remove.php: -------------------------------------------------------------------------------- 1 | serviceConfig = $config; 30 | $this->fileSystem = new Filesystem(); 31 | } 32 | 33 | /** 34 | * @param \OxidEsales\TestingLibrary\Services\Library\Request $request 35 | */ 36 | public function init($request) 37 | { 38 | $this->fileSystem->remove($request->getParameter(static::FILES_PARAMETER_NAME)); 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /library/Services/Library/Cache.php: -------------------------------------------------------------------------------- 1 | flush(); 23 | } 24 | } 25 | 26 | /** 27 | * Clears reverse proxy cache. 28 | */ 29 | public function clearReverseProxyCache() 30 | { 31 | if (class_exists('\OxidEsales\VarnishModule\Core\OeVarnishModule', false)) { 32 | \OxidEsales\VarnishModule\Core\OeVarnishModule::flushReverseProxyCache(); 33 | } 34 | if (class_exists('\OxidEsales\EshopEnterprise\Core\Cache\ReverseProxy\ReverseProxyBackend', false)) { 35 | $oReverseProxy = oxNew(\OxidEsales\EshopEnterprise\Core\Cache\ReverseProxy\ReverseProxyBackend::class); 36 | $oReverseProxy->setFlush(); 37 | $oReverseProxy->execute(); 38 | } 39 | } 40 | 41 | /** 42 | * Clears temporary directory. 43 | */ 44 | public function clearTemporaryDirectory() 45 | { 46 | if ($sCompileDir = \OxidEsales\Eshop\Core\Registry::get(\OxidEsales\Eshop\Core\ConfigFile::class)->getVar('sCompileDir')) { 47 | if (!is_writable($sCompileDir)) { 48 | CliExecutor::executeCommand("sudo chmod -R 777 $sCompileDir"); 49 | } 50 | $this->removeTemporaryDirectory($sCompileDir, false); 51 | } 52 | } 53 | 54 | /** 55 | * Delete all files and dirs recursively 56 | * 57 | * @param string $dir Directory to delete 58 | * @param bool $rmBaseDir Keep target directory 59 | */ 60 | private function removeTemporaryDirectory($dir, $rmBaseDir = false) 61 | { 62 | $itemsToIgnore = array('.', '..', '.htaccess'); 63 | 64 | $files = array_diff(scandir($dir), $itemsToIgnore); 65 | foreach ($files as $file) { 66 | if (is_dir("$dir/$file")) { 67 | $this->removeTemporaryDirectory( 68 | "$dir/$file", 69 | $file == 'smarty' ? $rmBaseDir : true 70 | ); 71 | } else { 72 | @unlink("$dir/$file"); 73 | } 74 | } 75 | if ($rmBaseDir) { 76 | @rmdir($dir); 77 | } 78 | } 79 | } 80 | -------------------------------------------------------------------------------- /library/Services/Library/CliExecutor.php: -------------------------------------------------------------------------------- 1 | 0) { 26 | $output = implode("\n", $output); 27 | throw new Exception("Failed to execute command: '$command' with output: '$output' "); 28 | } 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /library/Services/Library/DatabaseDefaultsFileGenerator.php: -------------------------------------------------------------------------------- 1 | config = $config; 24 | } 25 | 26 | /** 27 | * @return string File path. 28 | */ 29 | public function generate(): string 30 | { 31 | $file = sys_get_temp_dir() . DIRECTORY_SEPARATOR . uniqid('testing_lib', true) . '.cnf'; 32 | $resource = fopen($file, 'w'); 33 | $fileContents = "[client]" 34 | . "\nuser=" . $this->config->dbUser 35 | . "\npassword=" . $this->config->dbPwd 36 | . "\nhost=" . $this->config->dbHost 37 | . "\nport=" . $this->config->dbPort 38 | . "\n"; 39 | fwrite($resource, $fileContents); 40 | fclose($resource); 41 | chmod($file, 0750); 42 | return $file; 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /library/Services/Library/DatabaseRestorer/DatabaseRestorerFactory.php: -------------------------------------------------------------------------------- 1 | _getFileInfo($sFileIndex); 29 | 30 | if (!$this->_checkFile($aFileInfo)) { 31 | throw new Exception("File with index '$sFileIndex' does not exist or error occurred while downloading it"); 32 | } 33 | 34 | return $this->_moveUploadedFile($aFileInfo, $sLocation, $blOverwrite); 35 | } 36 | 37 | /** 38 | * Checks if file information (name and tmp_name) is set and no errors exists. 39 | * 40 | * @param array $fileInfo 41 | * 42 | * @return bool 43 | */ 44 | private function _checkFile($fileInfo) 45 | { 46 | $result = isset($fileInfo['name']) && isset($fileInfo['tmp_name']); 47 | 48 | if ($result && isset($fileInfo['error']) && $fileInfo['error']) { 49 | $result = false; 50 | } 51 | 52 | return $result; 53 | } 54 | 55 | /** 56 | * Returns file information. 57 | * 58 | * @param string $fileIndex 59 | * 60 | */ 61 | private function _getFileInfo($fileIndex) 62 | { 63 | return $_FILES[$fileIndex]; 64 | } 65 | 66 | /** 67 | * @param array $fileInfo 68 | * @param string $location 69 | * @param bool $overwrite 70 | * 71 | * @return bool 72 | */ 73 | private function _moveUploadedFile($fileInfo, $location, $overwrite) 74 | { 75 | $isDone = false; 76 | 77 | if (!file_exists($location) || $overwrite) { 78 | $isDone = move_uploaded_file($fileInfo['tmp_name'], $location); 79 | 80 | if ($isDone) { 81 | $isDone = @chmod($location, 0644); 82 | } 83 | } 84 | 85 | return $isDone; 86 | } 87 | } 88 | -------------------------------------------------------------------------------- /library/Services/Library/ProjectConfigurationHandler.php: -------------------------------------------------------------------------------- 1 | configurationHelper = $configurationHelper; 27 | } 28 | 29 | /** 30 | * Backup project configuration. 31 | * @throws FileNotFoundException 32 | */ 33 | public function backup(): void 34 | { 35 | if (!file_exists($this->getOriginalConfigurationPath())) { 36 | throw new FileNotFoundException('Unable to backup ' . $this->getOriginalConfigurationPath() . '. It does not exist.'); 37 | } 38 | $this->recursiveCopy($this->getOriginalConfigurationPath(), $this->getBackupConfigurationPath()); 39 | } 40 | 41 | /** 42 | * Restore project configuration. 43 | * @throws FileNotFoundException 44 | */ 45 | public function restore(): void 46 | { 47 | if (!file_exists($this->getBackupConfigurationPath())) { 48 | throw new FileNotFoundException('Unable to restore ' . $this->getBackupConfigurationPath() . '. It does not exist.'); 49 | } 50 | $this->rmdirRecursive($this->getOriginalConfigurationPath()); 51 | $this->recursiveCopy($this->getBackupConfigurationPath(), $this->getOriginalConfigurationPath()); 52 | $this->rmdirRecursive($this->getBackupConfigurationPath()); 53 | } 54 | 55 | /** 56 | * @return string 57 | */ 58 | private function getOriginalConfigurationPath(): string 59 | { 60 | return Path::join($this->configurationHelper->getConfigurationDirectoryPath()); 61 | } 62 | 63 | /** 64 | * @return string 65 | */ 66 | private function getBackupConfigurationPath(): string 67 | { 68 | return Path::join($this->configurationHelper->getConfigurationDirectoryPath() . '-backup'); 69 | } 70 | 71 | /** 72 | * @param string $source 73 | * @param string $destination 74 | */ 75 | private function recursiveCopy(string $source, string $destination) : void 76 | { 77 | $filesystem = new Filesystem(); 78 | $filesystem->mirror($source, $destination); 79 | } 80 | 81 | /** 82 | * @param string $directory 83 | */ 84 | private function rmdirRecursive(string $directory): void 85 | { 86 | $filesystem = new Filesystem(); 87 | $filesystem->remove($directory); 88 | } 89 | } 90 | -------------------------------------------------------------------------------- /library/Services/Library/Request.php: -------------------------------------------------------------------------------- 1 | parameters = $_REQUEST; 24 | if (!empty($parameters)) { 25 | $this->parameters = array_merge($this->parameters, $parameters); 26 | } 27 | } 28 | 29 | /** 30 | * Returns request parameter 31 | * 32 | * @param string $name 33 | * @param null $default 34 | * 35 | * @return mixed 36 | */ 37 | public function getParameter($name, $default = null) 38 | { 39 | return array_key_exists($name, $this->parameters) ? $this->parameters[$name] : $default; 40 | } 41 | 42 | /** 43 | * Returns uploaded file parameter 44 | * 45 | * @param string $name param name 46 | * 47 | * @return mixed 48 | */ 49 | public function getUploadedFile($name) 50 | { 51 | $filePath = ''; 52 | if (array_key_exists($name, $_FILES)) { 53 | $filePath = $_FILES[$name]['tmp_name']; 54 | } elseif (array_key_exists($name, $this->parameters)) { 55 | $filePath = substr($this->parameters[$name], 1); 56 | } 57 | 58 | return $filePath; 59 | } 60 | } 61 | -------------------------------------------------------------------------------- /library/Services/Library/ServiceConfig.php: -------------------------------------------------------------------------------- 1 | shopDirectory = $shopDirectory; 41 | if (empty($tempDirectory)) { 42 | $tempDirectory = $shopDirectory . '/temp'; 43 | } 44 | $this->tempDirectory = $tempDirectory; 45 | } 46 | 47 | /** 48 | * Returns path to shop source directory. 49 | * If shop path was not set, it assumes that services was copied to shop root directory. 50 | * 51 | * @return string 52 | */ 53 | public function getShopDirectory() 54 | { 55 | return $this->shopDirectory; 56 | } 57 | 58 | /** 59 | * Sets shop path. 60 | * 61 | * @param string $shopDirectory 62 | */ 63 | public function setShopDirectory($shopDirectory) 64 | { 65 | $this->shopDirectory = $shopDirectory; 66 | } 67 | 68 | 69 | /** 70 | * Returns shop edition 71 | * 72 | * @return array|null|string 73 | */ 74 | public function getShopEdition() 75 | { 76 | if (is_null($this->shopEdition)) { 77 | $shopEdition = (new Facts())->getEdition(); 78 | 79 | $this->shopEdition = strtoupper($shopEdition); 80 | } 81 | return $this->shopEdition; 82 | } 83 | 84 | /** 85 | * Sets shop path. 86 | * 87 | * @param string $shopEdition 88 | */ 89 | public function setShopEdition($shopEdition) 90 | { 91 | $this->shopEdition = $shopEdition; 92 | } 93 | 94 | /** 95 | * Returns temp path. 96 | * 97 | * @return string 98 | */ 99 | public function getTempDirectory() 100 | { 101 | if (!file_exists($this->tempDirectory)) { 102 | mkdir($this->tempDirectory, 0777); 103 | chmod($this->tempDirectory, 0777); 104 | } 105 | 106 | return $this->tempDirectory; 107 | } 108 | 109 | /** 110 | * Set temp path. 111 | * 112 | * @param string $tempPath 113 | */ 114 | public function setTempDirectory($tempPath) 115 | { 116 | $this->tempDirectory = $tempPath; 117 | } 118 | 119 | /** 120 | * Returns services root directory. 121 | * 122 | * @return string 123 | */ 124 | public function getServicesDirectory() 125 | { 126 | return __DIR__ .'/../'; 127 | } 128 | } 129 | -------------------------------------------------------------------------------- /library/Services/Library/ShopServiceInterface.php: -------------------------------------------------------------------------------- 1 | getParameter('shp')) && (1 < $shopId)) { 39 | $this->switchToShop($shopId); 40 | } 41 | 42 | (new ModuleLoader())->activateModules($request->getParameter("modulestoactivate")); 43 | 44 | $this->makeModuleServicesAvailableInDIContainer(); 45 | } 46 | 47 | /** 48 | * Switch to subshop. 49 | * 50 | * @param integer $shopId 51 | * 52 | * @return integer 53 | */ 54 | public function switchToShop($shopId) 55 | { 56 | $_POST['shp'] = $shopId; 57 | $_POST['actshop'] = $shopId; 58 | $keepThese = [\OxidEsales\Eshop\Core\ConfigFile::class]; 59 | $registryKeys = Registry::getKeys(); 60 | foreach ($registryKeys as $key) { 61 | if (in_array($key, $keepThese)) { 62 | continue; 63 | } 64 | Registry::set($key, null); 65 | } 66 | $utilsObject = \OxidEsales\Eshop\Core\UtilsObject::getInstance(); 67 | $utilsObject->resetInstanceCache(); 68 | Registry::set(\OxidEsales\Eshop\Core\UtilsObject::class, $utilsObject); 69 | \OxidEsales\Eshop\Core\Module\ModuleVariablesLocator::resetModuleVariables(); 70 | Registry::getSession()->setVariable('shp', $shopId); 71 | Registry::set(\OxidEsales\Eshop\Core\Config::class, null); 72 | $moduleVariablesCache = new \OxidEsales\Eshop\Core\FileCache(); 73 | $shopIdCalculator = new \OxidEsales\Eshop\Core\ShopIdCalculator($moduleVariablesCache); 74 | return $shopIdCalculator->getShopId(); 75 | } 76 | 77 | private function makeModuleServicesAvailableInDIContainer(): void 78 | { 79 | ContainerFactory::resetContainer(); 80 | } 81 | } 82 | -------------------------------------------------------------------------------- /library/Services/ServiceFactory.php: -------------------------------------------------------------------------------- 1 | config = $config; 25 | 26 | include_once $config->getShopDirectory() . '/bootstrap.php'; 27 | } 28 | 29 | /** 30 | * Creates Service object. All services must implement ShopService interface 31 | * 32 | * @param string $serviceClass 33 | * 34 | * @throws Exception 35 | * 36 | * @return ShopServiceInterface 37 | */ 38 | public function createService($serviceClass) 39 | { 40 | $className = $serviceClass; 41 | if (!$this->isNamespacedClass($serviceClass)) { 42 | // Used for backwards compatibility. 43 | $className = $this->formClassName($serviceClass); 44 | } 45 | if (!class_exists($className)) { 46 | throw new Exception("Service '$serviceClass' was not found!"); 47 | } 48 | $service = new $className($this->getServiceConfig()); 49 | 50 | if (!($service instanceof ShopServiceInterface)) { 51 | throw new Exception("Service '$className' does not implement ShopServiceInterface interface!"); 52 | } 53 | 54 | return $service; 55 | } 56 | 57 | /** 58 | * Includes service main class file 59 | * 60 | * @param string $serviceClass 61 | * 62 | * @return string 63 | */ 64 | protected function formClassName($serviceClass) 65 | { 66 | return "OxidEsales\\TestingLibrary\\Services\\$serviceClass\\$serviceClass"; 67 | } 68 | 69 | /** 70 | * @return ServiceConfig 71 | */ 72 | protected function getServiceConfig() 73 | { 74 | return $this->config; 75 | } 76 | 77 | /** 78 | * @param string $className 79 | * 80 | * @return bool 81 | */ 82 | private function isNamespacedClass($className) 83 | { 84 | return strpos($className, '\\') !== false; 85 | } 86 | } 87 | -------------------------------------------------------------------------------- /library/Services/ShopObjectConstructor/Constructor/ConstructorFactory.php: -------------------------------------------------------------------------------- 1 | formConstructorClass($sClassName); 21 | if (!class_exists($constructorClassName)) { 22 | $constructorClassName = $this->formConstructorClass('Object'); 23 | } 24 | 25 | return new $constructorClassName($sClassName); 26 | } 27 | 28 | /** 29 | * @param string $className 30 | * 31 | * @return bool|string 32 | */ 33 | protected function formConstructorClass($className) 34 | { 35 | $sConstructorClass = $className . "Constructor"; 36 | return "OxidEsales\\TestingLibrary\\Services\\ShopObjectConstructor\\Constructor\\$sConstructorClass"; 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /library/Services/ShopObjectConstructor/Constructor/ObjectConstructor.php: -------------------------------------------------------------------------------- 1 | object = $this->_createObject($className); 26 | } 27 | 28 | /** 29 | * Returns constructed object 30 | * 31 | * @return \OxidEsales\Eshop\Core\Model\BaseModel|object 32 | */ 33 | public function getObject() 34 | { 35 | return $this->object; 36 | } 37 | 38 | /** 39 | * Loads object by given id 40 | * 41 | * @param mixed $objectId 42 | * 43 | * @throws Exception 44 | */ 45 | public function load($objectId) 46 | { 47 | if (!empty($objectId)) { 48 | $blResult = is_array($objectId)? $this->_loadByArray($objectId) : $this->_loadById($objectId); 49 | if ($blResult === false) { 50 | $sClass = get_class($this->getObject()); 51 | throw new Exception("Failed to load $sClass with id $objectId"); 52 | } 53 | } 54 | } 55 | 56 | /** 57 | * @param string $objectId 58 | * 59 | * @return bool|mixed 60 | */ 61 | protected function _loadById($objectId) 62 | { 63 | if ($objectId == 'lastInsertedId') { 64 | $objectId = $this->_getLastInsertedId(); 65 | } 66 | $object = $this->getObject(); 67 | $result = $object->load($objectId); 68 | 69 | if ($result && $object->getId() != $objectId) { 70 | $result = $object->load($objectId); 71 | } 72 | 73 | return $result; 74 | } 75 | 76 | /** 77 | * @param array $objectIds 78 | * 79 | * @return mixed 80 | */ 81 | protected function _loadByArray($objectIds) 82 | { 83 | $function = key($objectIds); 84 | $id = current($objectIds); 85 | 86 | return $this->getObject()->$function($id); 87 | } 88 | 89 | /** 90 | * Sets class parameters 91 | * 92 | * @param array $classParams 93 | * @return array 94 | */ 95 | public function setClassParameters($classParams) 96 | { 97 | $object = $this->getObject(); 98 | $tableName = $object->getCoreTableName(); 99 | $values = array(); 100 | foreach ($classParams as $sParamKey => $paramValue) { 101 | if (is_int($sParamKey)) { 102 | $fieldName = $this->_getFieldName($tableName, $paramValue); 103 | $values[$paramValue] = $object->$fieldName->value; 104 | } else { 105 | $fieldName = $this->_getFieldName($tableName, $sParamKey); 106 | if (is_string($paramValue)) { 107 | $paramValue = html_entity_decode($paramValue); 108 | } 109 | $object->$fieldName = new \OxidEsales\Eshop\Core\Field($paramValue); 110 | } 111 | } 112 | 113 | return $values; 114 | } 115 | 116 | /** 117 | * Calls object function with given parameters. 118 | * 119 | * @param string $functionName 120 | * @param array $parameters 121 | * 122 | * @return mixed 123 | */ 124 | public function callFunction($functionName, $parameters) 125 | { 126 | $parameters = is_array($parameters) ? $parameters : array(); 127 | $response = call_user_func_array(array($this->getObject(), $functionName), $parameters); 128 | 129 | return $response; 130 | } 131 | 132 | /** 133 | * Returns created object to work with 134 | * 135 | * @param string $className 136 | * 137 | * @return object 138 | */ 139 | protected function _createObject($className) 140 | { 141 | return oxNew($className); 142 | } 143 | 144 | /** 145 | * @param string $tableName 146 | * @param string $paramValue 147 | * 148 | * @return string 149 | */ 150 | protected function _getFieldName($tableName, $paramValue) 151 | { 152 | $sResult = $tableName . '__' . $paramValue; 153 | if (strpos($paramValue, '__') !== false) { 154 | $sResult = $paramValue; 155 | } 156 | return strtolower($sResult); 157 | } 158 | 159 | /** 160 | * Get id of latest created row. 161 | * 162 | * @return string|null 163 | */ 164 | protected function _getLastInsertedId() 165 | { 166 | $objectId = null; 167 | $oDb = \OxidEsales\Eshop\Core\DatabaseProvider::getDb(\OxidEsales\Eshop\Core\DatabaseProvider::FETCH_MODE_ASSOC); 168 | 169 | $tableName = $this->getObject()->getCoreTableName(); 170 | $query = 'SELECT OXID FROM '. $tableName .' ORDER BY OXTIMESTAMP DESC LIMIT 1'; 171 | $result = $oDb->select($query); 172 | 173 | if ($result != false && $result->count() > 0) { 174 | $fields = $result->fields; 175 | $objectId = $fields['OXID']; 176 | } 177 | 178 | return $objectId; 179 | } 180 | } 181 | -------------------------------------------------------------------------------- /library/Services/ShopObjectConstructor/Constructor/oxBaseConstructor.php: -------------------------------------------------------------------------------- 1 | getObject()->init($objectId); 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /library/Services/ShopObjectConstructor/Constructor/oxConfigConstructor.php: -------------------------------------------------------------------------------- 1 | $configParameters) { 36 | if (is_int($sConfKey)) { 37 | $values[$configParameters] = $this->getObject()->getConfigParam($configParameters); 38 | } else { 39 | $aFormedParams = $this->_formSaveConfigParameters($sConfKey, $configParameters); 40 | if ($aFormedParams) { 41 | $this->callFunction("saveShopConfVar", $aFormedParams); 42 | } 43 | } 44 | } 45 | 46 | return $values; 47 | } 48 | 49 | /** 50 | * Returns created object to work with 51 | * 52 | * @param string $className 53 | * 54 | * @return \OxidEsales\Eshop\Core\Config 55 | */ 56 | protected function _createObject($className) 57 | { 58 | return oxNew(\OxidEsales\Eshop\Core\Config::class); 59 | } 60 | 61 | /** 62 | * Forms parameters for saveShopConfVar function from given parameters 63 | * 64 | * @param string $configKey 65 | * @param array $configParameters 66 | * @return array|bool 67 | */ 68 | private function _formSaveConfigParameters($configKey, $configParameters) 69 | { 70 | $type = null; 71 | if (isset($configParameters['type'])) { 72 | $type = $configParameters['type']; 73 | } 74 | 75 | $value = null; 76 | if (isset($configParameters['value'])) { 77 | $value = $configParameters['value']; 78 | } 79 | 80 | $module = null; 81 | if (isset($configParameters['module'])) { 82 | $module = $configParameters['module']; 83 | } 84 | 85 | if (($type == "arr" || $type == 'aarr') && !is_array($value)) { 86 | $value = unserialize(htmlspecialchars_decode($value)); 87 | } 88 | return !empty($type) ? array($type, $configKey, $value, null, $module) : false; 89 | } 90 | } 91 | -------------------------------------------------------------------------------- /library/Services/ShopObjectConstructor/Constructor/oxListConstructor.php: -------------------------------------------------------------------------------- 1 | getObject()->init($objectId, $objectId); 23 | } 24 | 25 | /** 26 | * Calls object function with given parameters 27 | * 28 | * @param string $functionName 29 | * @param array $parameters 30 | * @return mixed 31 | */ 32 | public function callFunction($functionName, $parameters) 33 | { 34 | if ($functionName == 'getList') { 35 | $oObject = $this->getObject(); 36 | $mResponse = $this->_formArrayFromList($oObject->getList()); 37 | } else { 38 | $mResponse = parent::callFunction($functionName, $parameters); 39 | } 40 | 41 | return $mResponse; 42 | } 43 | 44 | /** 45 | * Returns formed array with data from given list 46 | * 47 | * @param \OxidEsales\Eshop\Core\Model\ListModel|Iterator $oList 48 | * @return array 49 | */ 50 | protected function _formArrayFromList($oList) 51 | { 52 | $aData = array(); 53 | foreach ($oList as $sKey => $object) { 54 | $aData[$sKey] = $this->_getObjectFieldValues($object); 55 | } 56 | 57 | return $aData; 58 | } 59 | 60 | /** 61 | * Returns object field values 62 | * 63 | * @param \OxidEsales\Eshop\Core\Model\BaseModel|object $object 64 | * 65 | * @return array 66 | */ 67 | protected function _getObjectFieldValues($object) 68 | { 69 | $result = array(); 70 | $fields = $object->getFieldNames(); 71 | $tableName = $object->getCoreTableName(); 72 | foreach ($fields as $field) { 73 | $fieldName = $tableName.'__'.$field; 74 | $result[$field] = $object->$fieldName->value; 75 | } 76 | 77 | return $result; 78 | } 79 | } 80 | -------------------------------------------------------------------------------- /library/Services/ShopObjectConstructor/ShopObjectConstructor.php: -------------------------------------------------------------------------------- 1 | serviceConfig = $config; 30 | } 31 | 32 | /** 33 | * Loads object, sets class parameters and calls function with parameters. 34 | * classParams can act two ways - if array('param' => 'value') is given, it sets the values to given keys 35 | * if array('param', 'param') is passed, values of these params are returned. 36 | * classParams are only returned if no function is called. Otherwise function return value is returned. 37 | * 38 | * @param Request $request 39 | * 40 | * @return mixed 41 | */ 42 | public function init($request) 43 | { 44 | if (!is_null($request->getParameter('shp'))) { 45 | $this->setActiveShop($request->getParameter('shp')); 46 | } 47 | if (!is_null($request->getParameter('lang'))) { 48 | $this->setActiveLanguage($request->getParameter('lang')); 49 | } 50 | 51 | $oConstructorFactory = new ConstructorFactory(); 52 | $oConstructor = $oConstructorFactory->getConstructor($request->getParameter("cl")); 53 | 54 | $oConstructor->load($request->getParameter("oxid")); 55 | 56 | $mResult = ''; 57 | if ($request->getParameter('classparams')) { 58 | $mResult = $oConstructor->setClassParameters($request->getParameter('classparams')); 59 | } 60 | 61 | if ($request->getParameter('fnc')) { 62 | $mResult = $oConstructor->callFunction($request->getParameter('fnc'), $request->getParameter('functionparams')); 63 | } 64 | 65 | return $mResult; 66 | } 67 | 68 | /** 69 | * @return ServiceConfig 70 | */ 71 | protected function getServiceConfig() 72 | { 73 | return $this->serviceConfig; 74 | } 75 | 76 | /** 77 | * Switches active shop 78 | * 79 | * @param string $shopId 80 | */ 81 | protected function setActiveShop($shopId) 82 | { 83 | if ($shopId && $this->getServiceConfig()->getShopEdition() == 'EE') { 84 | \OxidEsales\Eshop\Core\Registry::getConfig()->setShopId($shopId); 85 | } 86 | } 87 | 88 | /** 89 | * Switches active language 90 | * 91 | * @param string $language 92 | * 93 | * @throws Exception 94 | */ 95 | protected function setActiveLanguage($language) 96 | { 97 | $languages = \OxidEsales\Eshop\Core\Registry::getLang()->getLanguageIds(); 98 | $languageId = array_search($language, $languages); 99 | if ($languageId === false) { 100 | throw new Exception("Language $language was not found or is not active in shop"); 101 | } 102 | \OxidEsales\Eshop\Core\Registry::getLang()->setBaseLanguage($languageId); 103 | } 104 | } 105 | -------------------------------------------------------------------------------- /library/Services/ShopPreparation/ShopPreparation.php: -------------------------------------------------------------------------------- 1 | databaseHandler = new DatabaseHandler($configFile, $config->getTempDirectory()); 37 | 38 | $factory = new DatabaseRestorerFactory(); 39 | $this->databaseRestorer = $factory->createRestorer(DatabaseRestorerToFile::class); 40 | } 41 | 42 | /** 43 | * Handles request parameters. 44 | * 45 | * @param Request $request 46 | */ 47 | public function init($request) 48 | { 49 | if ($file = $request->getUploadedFile('importSql')) { 50 | $databaseHandler = $this->getDatabaseHandler(); 51 | $databaseHandler->import($file); 52 | } 53 | 54 | if ($request->getParameter('dumpDB')) { 55 | $databaseRestorer = $this->getDatabaseRestorer(); 56 | $databaseRestorer->dumpDB($request->getParameter('dump-prefix')); 57 | } 58 | 59 | if ($request->getParameter('restoreDB')) { 60 | $databaseRestorer = $this->getDatabaseRestorer(); 61 | $databaseRestorer->restoreDB($request->getParameter('dump-prefix')); 62 | } 63 | } 64 | 65 | /** 66 | * @return DatabaseHandler 67 | */ 68 | protected function getDatabaseHandler() 69 | { 70 | return $this->databaseHandler; 71 | } 72 | 73 | /** 74 | * @return DatabaseRestorerInterface 75 | */ 76 | protected function getDatabaseRestorer() 77 | { 78 | return $this->databaseRestorer; 79 | } 80 | } 81 | -------------------------------------------------------------------------------- /library/Services/SubShopHandler/SubShopHandler.php: -------------------------------------------------------------------------------- 1 | getParameter("elementtable"); 31 | $sShopId = $request->getParameter("shopid"); 32 | $sParentShopId = $request->getParameter("parentshopid"); 33 | $sElementId = $request->getParameter("elementid"); 34 | if ($sElementId) { 35 | $this->assignElementToSubShop($sElementTable, $sShopId, $sElementId); 36 | } else { 37 | $this->assignAllElementsToSubShop($sElementTable, $sShopId, $sParentShopId); 38 | } 39 | } 40 | 41 | /** 42 | * Assigns element to subshop 43 | * 44 | * @param string $sElementTable Name of element table 45 | * @param integer $sShopId Subshop id 46 | * @param integer $sElementId Element id 47 | */ 48 | public function assignElementToSubShop($sElementTable, $sShopId, $sElementId) 49 | { 50 | /** @var BaseModel $oBase */ 51 | $oBase = oxNew(\OxidEsales\Eshop\Core\Model\BaseModel::class); 52 | $oBase->init($sElementTable); 53 | if ($oBase->load($sElementId)) { 54 | /** @var \OxidEsales\Eshop\Core\Element2ShopRelations $oElement2ShopRelations */ 55 | $oElement2ShopRelations = oxNew(\OxidEsales\Eshop\Core\Element2ShopRelations::class, $sElementTable); 56 | $oElement2ShopRelations->setShopIds($sShopId); 57 | $oElement2ShopRelations->addToShop($oBase->getId()); 58 | } 59 | } 60 | 61 | /** 62 | * Assigns element to subshop 63 | * 64 | * @param string $sElementTable Name of element table 65 | * @param integer $sShopId Subshop id 66 | * @param integer $sParentShopId Parent subshop id 67 | */ 68 | public function assignAllElementsToSubShop($sElementTable, $sShopId, $sParentShopId = 1) 69 | { 70 | /** @var \OxidEsales\Eshop\Core\Element2ShopRelations $oElement2ShopRelations */ 71 | $oElement2ShopRelations = oxNew(\OxidEsales\Eshop\Core\Element2ShopRelations::class, $sElementTable); 72 | $oElement2ShopRelations->setShopIds($sShopId); 73 | $oElement2ShopRelations->inheritFromShop($sParentShopId); 74 | } 75 | } 76 | -------------------------------------------------------------------------------- /library/Services/ThemeSwitcher/ThemeSwitcher.php: -------------------------------------------------------------------------------- 1 | getParameter('themeName'); 31 | $shopId = $request->getParameter('shp'); 32 | 33 | $currentShopId = \OxidEsales\Eshop\Core\Registry::getConfig()->getShopId(); 34 | \OxidEsales\Eshop\Core\Registry::getConfig()->setShopId($shopId); 35 | 36 | $theme = oxNew( \OxidEsales\Eshop\Core\Theme::class); 37 | $theme->load($themeName); 38 | $theme->activate(); 39 | 40 | \OxidEsales\Eshop\Core\Registry::getConfig()->setShopId($currentShopId); 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /library/Services/ViewsGenerator/ViewsGenerator.php: -------------------------------------------------------------------------------- 1 | updateViews(); 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /library/Services/service.php: -------------------------------------------------------------------------------- 1 | createService($request->getParameter('service')); 42 | $response = $service->init($request); 43 | 44 | echo serialize($response); 45 | -------------------------------------------------------------------------------- /library/ShopStateBackup.php: -------------------------------------------------------------------------------- 1 | registryCache = array(); 47 | foreach (\OxidEsales\Eshop\Core\Registry::getKeys() as $class) { 48 | $instance = \OxidEsales\Eshop\Core\Registry::get($class); 49 | $this->registryCache[$class] = clone $instance; 50 | } 51 | } 52 | 53 | /** 54 | * Cleans up the registry 55 | */ 56 | public function resetRegistry() 57 | { 58 | $aRegKeys = \OxidEsales\Eshop\Core\Registry::getKeys(); 59 | 60 | $aSkippedClasses = array(); 61 | 62 | foreach ($aRegKeys as $sKey) { 63 | if (!in_array($sKey, $aSkippedClasses)) { 64 | $oInstance = null; 65 | if (!isset($this->registryCache[$sKey])) { 66 | try { 67 | $oNewInstance = oxNew($sKey); 68 | $this->registryCache[$sKey] = $oNewInstance; 69 | } catch (\OxidEsales\Eshop\Core\Exception\SystemComponentException $oException) { 70 | \OxidEsales\Eshop\Core\Registry::set($sKey, null); 71 | continue; 72 | } 73 | } 74 | $oInstance = clone $this->registryCache[$sKey]; 75 | \OxidEsales\Eshop\Core\Registry::set($sKey, $oInstance); 76 | } 77 | } 78 | } 79 | 80 | /** 81 | * Backs up global request variables for reverting them back after test run. 82 | */ 83 | public function backupRequestVariables() 84 | { 85 | $this->requestCache['_SERVER'] = $_SERVER; 86 | $this->requestCache['_POST'] = $_POST; 87 | $this->requestCache['_GET'] = $_GET; 88 | $this->requestCache['_SESSION'] = $_SESSION; 89 | $this->requestCache['_COOKIE'] = $_COOKIE; 90 | } 91 | 92 | /** 93 | * Sets global request variables to backed up ones after every test run. 94 | */ 95 | public function resetRequestVariables() 96 | { 97 | $_SERVER = $this->requestCache['_SERVER']; 98 | $_POST = $this->requestCache['_POST']; 99 | $_GET = $this->requestCache['_GET']; 100 | $_SESSION = $this->requestCache['_SESSION']; 101 | $_COOKIE = $this->requestCache['_COOKIE']; 102 | } 103 | } 104 | -------------------------------------------------------------------------------- /library/TestSqlPathProvider.php: -------------------------------------------------------------------------------- 1 | editionSelector = $editionSelector; 44 | $this->shopPath = $shopPath; 45 | } 46 | 47 | /** 48 | * Method returns path to test data according edition. 49 | * 50 | * @param string $testSuitePath 51 | * 52 | * @return string 53 | */ 54 | public function getDataPathBySuitePath($testSuitePath) 55 | { 56 | $pathToTestData = $testSuitePath; 57 | if ($this->getEditionSelector()->isEnterprise()) { 58 | $pathToTestData = $this->updatePathToTestSql($testSuitePath); 59 | } 60 | 61 | return $pathToTestData . '/' . static::TEST_SQL_DIRECTORY; 62 | } 63 | 64 | /** 65 | * @return EditionSelector 66 | */ 67 | protected function getEditionSelector() 68 | { 69 | return $this->editionSelector; 70 | } 71 | 72 | /** 73 | * @return string 74 | */ 75 | protected function getShopPath() 76 | { 77 | return $this->shopPath; 78 | } 79 | 80 | /** 81 | * Updates provided path for enterprise edition. 82 | * 83 | * @param string $pathToTestSql 84 | * 85 | * @return string 86 | */ 87 | protected function updatePathToTestSql($pathToTestSql) 88 | { 89 | $pathParts = explode('/' . static::ACCEPTANCE_DIRECTORY, $pathToTestSql); 90 | if (count($pathParts) > 1) { 91 | /** @var Utilities $utilities */ 92 | $testDirectoryName = $pathParts[(int)count($pathParts) - 1]; 93 | $pathToEditionTestDirectory = Path::join( 94 | (new Facts())->getVendorPath(), 95 | Facts::COMPOSER_VENDOR_OXID_ESALES, 96 | 'tests-deprecated-ee', 97 | ucfirst(static::ACCEPTANCE_DIRECTORY), 98 | $testDirectoryName 99 | ); 100 | 101 | $pathToTestSql = realpath($pathToEditionTestDirectory); 102 | } 103 | 104 | return $pathToTestSql; 105 | } 106 | } 107 | -------------------------------------------------------------------------------- /library/Translator.php: -------------------------------------------------------------------------------- 1 | _aUntranslated = $aUntranslated; 36 | } 37 | 38 | /** 39 | * $_aUntranslated getter 40 | * 41 | * @return array 42 | */ 43 | public function getUntranslated() 44 | { 45 | return $this->_aUntranslated; 46 | } 47 | 48 | /** 49 | * @var $_aKeys array variable 50 | */ 51 | protected $_aKeys; 52 | 53 | /** 54 | * @var $_sTranslationPattern string variable 55 | */ 56 | protected $_sTranslationPattern = '%(?[a-zA-Z0-9_]+)%'; 57 | 58 | /** 59 | * $_sTranslationPattern setter 60 | * 61 | * @param string $sTranslationPattern 62 | */ 63 | public function setTranslationPattern($sTranslationPattern) 64 | { 65 | $this->_sTranslationPattern = $sTranslationPattern; 66 | } 67 | 68 | /** 69 | * $_sTranslationPattern getter 70 | * 71 | * @return string 72 | */ 73 | public function getTranslationPattern() 74 | { 75 | return $this->_sTranslationPattern; 76 | } 77 | 78 | /** 79 | * $_aKeys setter 80 | * 81 | * @param array $aKeys 82 | */ 83 | protected function _setKeys($aKeys) 84 | { 85 | $this->_aKeys = $aKeys; 86 | } 87 | 88 | /** 89 | * $_aKeys getter 90 | * 91 | * @return array 92 | */ 93 | protected function _getKeys() 94 | { 95 | return $this->_aKeys; 96 | } 97 | 98 | 99 | /** 100 | * Sets admin value 101 | * 102 | * @param $blAdmin 103 | * 104 | */ 105 | public function setAdmin($blAdmin) 106 | { 107 | $this->_blAdmin = $blAdmin; 108 | } 109 | 110 | /** 111 | * Returns Admin value 112 | * 113 | * @return bool 114 | */ 115 | public function getAdmin() 116 | { 117 | return $this->_blAdmin; 118 | } 119 | 120 | /** 121 | * $_iLanguage setter 122 | * 123 | * @param integer $iLanguage 124 | */ 125 | public function setLanguage($iLanguage) 126 | { 127 | $this->_iLanguage = $iLanguage; 128 | } 129 | 130 | /** 131 | * $_iLanguage setter by language name 132 | * 133 | * @param string $sName 134 | */ 135 | public function setLanguageByName($sName) 136 | { 137 | $this->_iLanguage = $this->getLanguageIdByName($sName); 138 | } 139 | 140 | /** 141 | * $_iLanguage getter 142 | * 143 | * @return integer 144 | */ 145 | public function getLanguage() 146 | { 147 | return $this->_iLanguage; 148 | } 149 | 150 | /** 151 | * @param int $iLanguage 152 | * @param bool $blAdmin 153 | */ 154 | public function __construct($iLanguage = 1, $blAdmin = false) 155 | { 156 | $this->setLanguage($iLanguage); 157 | $this->setAdmin($blAdmin); 158 | } 159 | 160 | 161 | public function translate($sString) 162 | { 163 | $aUntranslated = array(); 164 | if (!$this->_isTranslateAble($sString)) { 165 | return $sString; 166 | } 167 | 168 | $iLang = $this->getLanguage(); 169 | $blAdmin = $this->getAdmin(); 170 | $aTranslations = array(); 171 | $aKeys = $this->_getKeys(); 172 | foreach ($aKeys as $sKey) { 173 | $aTranslations[$sKey] = \OxidEsales\Eshop\Core\Registry::getLang()->translateString($sKey, $iLang, $blAdmin); 174 | 175 | if ($aTranslations[$sKey] == $sKey) { 176 | $aUntranslated[] = $sKey; 177 | } 178 | } 179 | $this->setUntranslated($aUntranslated); 180 | 181 | $aNewKeys = array(); 182 | foreach ($aKeys as $sKey => $sValue) { 183 | if (in_array($sValue, $aUntranslated)) { 184 | $aNewKeys[$sKey] = $sValue; 185 | } else { 186 | $aNewKeys[$sKey] = "%$sValue%"; 187 | } 188 | } 189 | return str_replace($aNewKeys, $aTranslations, $sString); 190 | } 191 | 192 | 193 | /** 194 | * Checks if string can be translated 195 | * 196 | * @param $sString 197 | * 198 | * @return bool 199 | */ 200 | protected function _isTranslateAble($sString) 201 | { 202 | $sPattern = $this->getTranslationPattern(); 203 | $aMatches = array(); 204 | if (is_array($sString)) { 205 | $sString = implode('_DELIMITER_', $sString); 206 | } 207 | preg_match_all("|{$sPattern}|", $sString, $aMatches); 208 | 209 | if ($aMatches['key'] > 0) { 210 | $this->_setKeys($aMatches['key']); 211 | return true; 212 | } 213 | return false; 214 | } 215 | 216 | /** 217 | * @param string $sName 218 | * 219 | * @return int 220 | */ 221 | public function getLanguageIdByName($sName) 222 | { 223 | return array_search($sName, \OxidEsales\Eshop\Core\Registry::getLang()->getLanguageNames()); 224 | } 225 | } 226 | -------------------------------------------------------------------------------- /library/VfsStreamWrapper.php: -------------------------------------------------------------------------------- 1 | root = vfsStream::setup(self::ROOT_DIRECTORY); 29 | } 30 | 31 | /** 32 | * Creates file with given content. 33 | * If file contains path, directories will also be created. 34 | * Creating multiple files in the same directory does not work as 35 | * parent directories gets cleared on creation. 36 | * 37 | * NOTE: this can be used only once! If you call it twice, 38 | * the first file is gone and not found by is_file, 39 | * file_exists and others! 40 | * 41 | * @param string $filePath 42 | * @param string $content Will try to convent any value to string if non string is given. 43 | * 44 | * @return string Path to created file. 45 | */ 46 | public function createFile($filePath, $content = '') 47 | { 48 | $this->createStructure([ltrim($filePath, '/') => $content]); 49 | return $this->getRootPath() . $filePath; 50 | } 51 | 52 | /** 53 | * Creates whole directory structure. 54 | * Structure example: ['dir' => ['subdir' => ['file' => 'content']]]. 55 | * 56 | * @param array $structure 57 | * 58 | * @return string Path to root directory 59 | */ 60 | public function createStructure($structure) 61 | { 62 | vfsStream::create($this->prepareStructure($structure), $this->getRoot()); 63 | 64 | return $this->getRootPath(); 65 | } 66 | 67 | /** 68 | * Returns root url. It should be treated as usual file path. 69 | * 70 | * @return string 71 | */ 72 | public function getRootPath() 73 | { 74 | return vfsStream::url(self::ROOT_DIRECTORY) . DIRECTORY_SEPARATOR; 75 | } 76 | 77 | /** 78 | * Returns vfsStream root directory. 79 | * Root directory will only be created once, as recreating will cause 80 | * destroyal of the old one and of all the files created. 81 | * 82 | * @return vfsStreamDirectory 83 | */ 84 | public function getRoot() 85 | { 86 | return $this->root; 87 | } 88 | 89 | /** 90 | * @param array $structure 91 | * 92 | * @return array 93 | */ 94 | private function prepareStructure($structure) 95 | { 96 | $newStructure = []; 97 | foreach ($structure as $path => $element) { 98 | $position = &$newStructure; 99 | foreach (explode('/', $path) as $part) { 100 | $position[$part] = []; 101 | $position = &$position[$part]; 102 | } 103 | $position = strpos($path, DIRECTORY_SEPARATOR) === false ? [] : $position; 104 | $position = is_array($element) ? $this->prepareStructure($element) : (string) $element; 105 | } 106 | return $newStructure; 107 | } 108 | 109 | } 110 | -------------------------------------------------------------------------------- /library/_cc.php: -------------------------------------------------------------------------------- 1 | exceptionLogFile = $exceptionLogFile; 36 | } 37 | 38 | /** 39 | * Return the complete content of the exception log file as a string. 40 | * 41 | * @return string Content of the exception log file 42 | * 43 | * @throws \OxidEsales\Eshop\Core\Exception\StandardException if log file contend could not be read 44 | */ 45 | public function getExceptionLogFileContent() 46 | { 47 | $fileCreated = false; 48 | 49 | /** Suppress the warning, which is emitted, if the file does not exist */ 50 | if ($fileDoesNotExist = !@file_exists($this->exceptionLogFile)) { 51 | $fileCreated = touch($this->exceptionLogFile); 52 | } 53 | if ($fileDoesNotExist && !$fileCreated) { 54 | throw new \OxidEsales\Eshop\Core\Exception\StandardException('Empty file ' . $this->exceptionLogFile . ' could not have been be created'); 55 | } 56 | 57 | $logFileContent = file_get_contents($this->exceptionLogFile); 58 | if (false === $logFileContent) { 59 | throw new \OxidEsales\Eshop\Core\Exception\StandardException('File ' . $this->exceptionLogFile . ' could not be read'); 60 | } 61 | 62 | return $logFileContent; 63 | } 64 | 65 | /** 66 | * Use this method in _justified_ cases to clear exception log, e.g. if you are testing exceptions and their behavior. 67 | * Do _not_ use this method to silence exceptions, if you do not understand why they are thrown or if you are too lazy to fix the root cause. 68 | * 69 | * @throws \OxidEsales\Eshop\Core\Exception\StandardException 70 | */ 71 | public function clearExceptionLogFile() 72 | { 73 | if (!$filePointerResource = fopen($this->exceptionLogFile, 'w')) { 74 | throw new \OxidEsales\Eshop\Core\Exception\StandardException('File ' . $this->exceptionLogFile . ' could not be opened in write mode'); 75 | } 76 | if (!fclose($filePointerResource)) { 77 | throw new \OxidEsales\Eshop\Core\Exception\StandardException('File pointer resource for file ' . $this->exceptionLogFile . ' could not be closed'); 78 | }; 79 | } 80 | 81 | 82 | /** 83 | * Return an array of arrays with parsed exception lines 84 | * 85 | * @return array 86 | */ 87 | public function getParsedExceptions() 88 | { 89 | $parsedExceptions = []; 90 | 91 | $exceptions = $this->getExceptionLinesFromLogFile(); 92 | foreach ($exceptions as $exception) { 93 | $parsedExceptions[] = str_replace('\\\\', '\\', $exception); 94 | } 95 | 96 | return $parsedExceptions; 97 | } 98 | 99 | /** 100 | * Return an array, which only contains the lines with information about the exception, not the whole stacktrace 101 | * 102 | * @return array 103 | * 104 | * @throws \OxidEsales\Eshop\Core\Exception\StandardException 105 | */ 106 | protected function getExceptionLinesFromLogFile() 107 | { 108 | $exceptionLogLines = file($this->exceptionLogFile, FILE_IGNORE_NEW_LINES); 109 | if (false === $exceptionLogLines) { 110 | throw new \OxidEsales\Eshop\Core\Exception\StandardException('File ' . $this->exceptionLogFile . ' could not be read'); 111 | } 112 | 113 | $exceptionEntries = array_filter( 114 | $exceptionLogLines, 115 | function ($entry) { 116 | return false !== strpos($entry, '.ERROR') && false !== strpos($entry, 'Exception'); 117 | } 118 | ); 119 | 120 | return $exceptionEntries; 121 | } 122 | } 123 | -------------------------------------------------------------------------------- /library/helpers/modOxUtilsDate.php: -------------------------------------------------------------------------------- 1 | _sTime = $sTime; 22 | } 23 | 24 | /** 25 | * @return string 26 | */ 27 | public function getTime() 28 | { 29 | if (!is_null($this->_sTime)) { 30 | return $this->_sTime; 31 | } 32 | 33 | return parent::getTime(); 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /library/helpers/oxAdminViewHelper.php: -------------------------------------------------------------------------------- 1 | cleanup(); 21 | parent::__construct($params); 22 | } 23 | 24 | /** 25 | * Clean oxArticle static variables. 26 | */ 27 | public static function cleanup() 28 | { 29 | self::resetArticleCategories(); 30 | self::resetArticleCache(); 31 | self::resetAmountPrice(); 32 | } 33 | 34 | /** 35 | * Get private field value. 36 | * 37 | * @param string $name Field name 38 | * 39 | * @return mixed 40 | */ 41 | public function getVar($name) 42 | { 43 | return $this->{'_' . $name}; 44 | } 45 | 46 | /** 47 | * Set private field value. 48 | * 49 | * @param string $name Field name 50 | * @param string $value Field value 51 | */ 52 | public function setVar($name, $value) 53 | { 54 | $this->{'_' . $name} = $value; 55 | } 56 | 57 | /** 58 | * Reset cached private variable values. 59 | */ 60 | public static function resetArticleCache() 61 | { 62 | parent::$_aArticleVendors = array(); 63 | parent::$_aArticleManufacturers = array(); 64 | parent::$_aLoadedParents = null; 65 | parent::$_aSelList = null; 66 | } 67 | 68 | /** 69 | * Clean private variable values. 70 | */ 71 | public static function resetArticleCategories() 72 | { 73 | parent::$_aArticleCats = array(); 74 | } 75 | 76 | /** 77 | * Reset cached private variable values. 78 | */ 79 | public static function resetAmountPrice() 80 | { 81 | parent::$_blHasAmountPrice = null; 82 | } 83 | } 84 | -------------------------------------------------------------------------------- /library/helpers/oxBaseHelper.php: -------------------------------------------------------------------------------- 1 | database = $database; 18 | $this->database->forceMasterConnection(); 19 | } 20 | 21 | /** 22 | * @param string $tableName 23 | * @param string $fieldName 24 | * 25 | * @return object 26 | */ 27 | public function getFieldInformation($tableName, $fieldName) 28 | { 29 | $columns = $this->database->metaColumns($tableName); 30 | 31 | foreach($columns as $column) { 32 | if ($column->name === $fieldName) { 33 | 34 | return $column; 35 | } 36 | } 37 | 38 | return null; 39 | } 40 | 41 | /** 42 | * @param string $tableName 43 | */ 44 | public function dropView($tableName) 45 | { 46 | if ($this->existsView($tableName)) { 47 | $generator = oxNew(\OxidEsales\Eshop\Core\TableViewNameGenerator::class); 48 | $tableNameView = $generator->getViewName($tableName, 0); 49 | 50 | $this->database->execute("DROP VIEW " . $this->database->quoteIdentifier($tableNameView)); 51 | } 52 | } 53 | 54 | /** 55 | * @param string $tableName 56 | * 57 | * @return bool Does the view with the given name exists? 58 | */ 59 | public function existsView($tableName) 60 | { 61 | $generator = oxNew(\OxidEsales\Eshop\Core\TableViewNameGenerator::class); 62 | $tableNameView = $generator->getViewName($tableName, 0); 63 | $sql = "SHOW TABLES LIKE '$tableNameView'"; 64 | 65 | return $tableNameView === $this->database->getOne($sql); 66 | } 67 | 68 | /** 69 | * @param string $tableName The name of the table we want to assure to exist. 70 | * 71 | * @return bool Does the database table with the given name exists? 72 | */ 73 | public function existsTable($tableName) 74 | { 75 | $sql = "SELECT COUNT(TABLE_NAME) FROM information_schema.TABLES WHERE TABLE_NAME = '$tableName'"; 76 | 77 | $count = $this->database->getOne($sql); 78 | 79 | return $count > 0; 80 | } 81 | 82 | public function adjustTemplateBlocksOxModuleColumn() 83 | { 84 | $sql = "ALTER TABLE `oxtplblocks` 85 | CHANGE `OXMODULE` `OXMODULE` char(32) 86 | character set latin1 collate latin1_general_ci NOT NULL 87 | COMMENT 'Module, which uses this template';"; 88 | 89 | $this->database->execute($sql); 90 | } 91 | 92 | public function getDataBaseTables() 93 | { 94 | $shopConfigFile = \OxidEsales\Eshop\Core\Registry::get(\OxidEsales\Eshop\Core\ConfigFile::class); 95 | $databaseHandler = new DatabaseHandler($shopConfigFile); 96 | 97 | $sql = "SELECT SCHEMA_NAME FROM INFORMATION_SCHEMA.SCHEMATA WHERE SCHEMA_NAME = '" . $databaseHandler->getDbName() . "'"; 98 | 99 | return $this->database->getAll($sql); 100 | } 101 | } 102 | -------------------------------------------------------------------------------- /library/helpers/oxDeliveryHelper.php: -------------------------------------------------------------------------------- 1 | _blWasSubscribed = $wasSubscribed; 22 | } 23 | 24 | /** 25 | * Returns whether user was subscribed. 26 | * 27 | * @return bool 28 | */ 29 | public function getWasSubscribed() 30 | { 31 | return $this->_blWasSubscribed; 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /library/helpers/oxSeoEncoderHelper.php: -------------------------------------------------------------------------------- 1 | aCache = array_merge($this->aCache, $mKey); 47 | } else { 48 | $this->aCache[$mKey] = $mValue; 49 | } 50 | } 51 | 52 | /** 53 | * Returns cached item value. 54 | * 55 | * @param array|string $mKey 56 | * @return array 57 | */ 58 | public function get($mKey) 59 | { 60 | if (is_array($mKey)) { 61 | return array_intersect_key($this->aCache, array_flip($mKey)); 62 | } else { 63 | return $this->aCache[$mKey]; 64 | } 65 | } 66 | 67 | /** 68 | * Invalidates item's cache. 69 | * 70 | * @param array|string $mKey 71 | * 72 | */ 73 | public function invalidate($mKey) 74 | { 75 | if (is_array($mKey)) { 76 | $this->aCache = array_diff_key($this->aCache, array_flip($mKey)); 77 | } else { 78 | $this->aCache[$mKey] = null; 79 | } 80 | 81 | } 82 | 83 | /** 84 | * Clears cache 85 | */ 86 | public function flush() 87 | { 88 | $this->aCache = array(); 89 | } 90 | } 91 | -------------------------------------------------------------------------------- /library/helpers/oxUBaseHelper.php: -------------------------------------------------------------------------------- 1 | initWasCalled = true; 30 | } 31 | 32 | /** 33 | * Cleans classes static variables. 34 | */ 35 | public static function cleanup() 36 | { 37 | self::resetComponentNames(); 38 | } 39 | 40 | /** 41 | * Sets class parent. 42 | * 43 | * @param null $oParam 44 | */ 45 | public function setParent($oParam = null) 46 | { 47 | $this->setParentWasCalled = true; 48 | } 49 | 50 | /** 51 | * Sets action. 52 | * 53 | * @param null $oParam 54 | */ 55 | public function setThisAction($oParam = null) 56 | { 57 | $this->setThisActionWasCalled = true; 58 | } 59 | 60 | /** 61 | * Resets collected component names. 62 | */ 63 | public static function resetComponentNames() 64 | { 65 | parent::$_aCollectedComponentNames = null; 66 | } 67 | } 68 | -------------------------------------------------------------------------------- /library/helpers/oxUtilsFileHelper.php: -------------------------------------------------------------------------------- 1 | 2 | 20 | 21 | -------------------------------------------------------------------------------- /test_config.yml.dist: -------------------------------------------------------------------------------- 1 | # parameters for testing library 2 | mandatory_parameters: 3 | # Path to eShop source. Defaults to the same directory as to where vendor is located. 4 | shop_path: 'source' 5 | 6 | # Path to eShop tests 7 | shop_tests_path: 'vendor/oxid-esales/tests-deprecated-ce' 8 | 9 | # When testing installed modules, specify the module id within shop. 10 | # Multiple module ids can be specified separated by comma: 'module1_id,module2_id,module3_id'. 11 | module_ids: 12 | 13 | optional_parameters: 14 | # eShop base url (if not set, takes it from shop's config.inc.php file) 15 | shop_url: 16 | 17 | # For PE and EE editions shop serial has to be specified for shop installer to work. 18 | shop_serial: '' 19 | 20 | # Run tests with varnish on. Shop has to be configured to work with varnish, correct serial must be used. 21 | enable_varnish: false 22 | 23 | # Whether to run subshop tests. Currently only used when running selenium tests. 24 | is_subshop: false 25 | 26 | # Whether to prepare shop database for testing. Shop config.ing.php file must be correct. 27 | install_shop: true 28 | 29 | # If defined, testing services will be copied to this directory and called via url instead of used locally. 30 | # Example: username@server.com:/path/to/shop 31 | remote_server_dir: 32 | 33 | # eShop setup directory. After setting up the shop, setup directory will be deleted. 34 | # For shop installation to work during tests run, path to this directory must be specified. 35 | # Uses shop/directory/Setup/ if not set. 36 | shop_setup_path: 37 | 38 | # Whether to restore shop data after running all tests. If this is set to false, shop will be left with tests data added on it. 39 | restore_shop_after_tests_suite: false 40 | 41 | # If specified, this database is used instead of real one for unit and integration tests. 42 | test_database_name: 43 | 44 | # Whether to dump and restore the database after a single acceptance test. 45 | restore_after_acceptance_tests: true 46 | 47 | # Whether to dump and restore the database after all tests are finished in a single unit, integration test suite. 48 | restore_after_unit_tests: true 49 | 50 | # If php has no write access to /tmp folder, provide alternative temp folder for tests. 51 | tmp_path: /tmp/oxid_test_library/ 52 | 53 | # Currently exists DatabaseRestorer and LocalDatabaseRestorer. 54 | # DatabaseRestorer - used with external database. 55 | # DatabaseRestorerLocal - used with local database (faster). 56 | # DatabaseRestorerToFile - used for selenium tests, but can also be used for units. 57 | database_restoration_class: 'DatabaseRestorer' 58 | 59 | # Whether to activate all modules defined in module_ids when running tests. 60 | # Normally only tested module is activated during test run. Modules will be activated in the specified order. 61 | activate_all_modules: false 62 | 63 | # Whether to run shop unit tests. This applies only when correct shop_tests_path are set. 64 | run_tests_for_shop: true 65 | 66 | # Whether to run modules unit tests. All modules provided in module_ids will be tested. 67 | # If shop_tests_path and run_shop_tests are set, shop tests will be run with module tests. 68 | run_tests_for_modules: true 69 | 70 | # Folder where to save selenium screen shots. If not specified, screenshots will not be taken. 71 | screen_shots_path: null 72 | 73 | # Url, where selenium screen shots should be available. 74 | screen_shots_url: null 75 | 76 | # Browser name which will be used for acceptance testing. 77 | # Possible values: *iexplore, *iehta, *firefox, *chrome, *piiexplore, *pifirefox, *safari, *opera. 78 | # Make sure that path to browser executable is known for the system. 79 | browser_name: 'firefox' 80 | 81 | # Selenium server IP address. Used to connect to selenium server when Mink selenium driver is used for acceptance tests. 82 | selenium_server_ip: '127.0.0.1' 83 | 84 | # Selenium server port. Used to connect to selenium server when Mink selenium driver is used for acceptance tests. 85 | selenium_server_port: '4444' 86 | 87 | # For running additional tests, please specify paths separated by commas. 88 | additional_test_paths: 'vendor/oxid-esales/tests-deprecated-pe,vendor/oxid-esales/tests-deprecated-ee' 89 | 90 | # How many times to try test before marking it as failure. 91 | # Could be used for unstable tests which fails randomly. 92 | retry_times_after_test_fail: 2 93 | -------------------------------------------------------------------------------- /tests/Integration/Services/Files/ChangeExceptionLogRightsTest.php: -------------------------------------------------------------------------------- 1 | ['oxid.log' => 'content']]); 19 | $pathToExceptionLog = "$rootPath/log/oxideshop.log"; 20 | chmod($pathToExceptionLog, 0111); 21 | 22 | $this->assertFalse(is_writable($pathToExceptionLog)); 23 | 24 | $changeRightsService = new ChangeExceptionLogRights(new ServiceConfig($rootPath)); 25 | $changeRightsService->init($request = new Request()); 26 | 27 | $filePermissions = $this->getFilePermissions($pathToExceptionLog); 28 | $this->assertSame('0777', $filePermissions, 'Exception log should be writable.'); 29 | } 30 | 31 | public function testCreateWhenFileDoesNotExist() 32 | { 33 | $rootPath = FilesHelper::prepareStructureAndReturnPath(['log' => []]); 34 | $pathToExceptionLog = "$rootPath/log/oxideshop.log"; 35 | 36 | $this->assertFalse(file_exists($pathToExceptionLog)); 37 | 38 | $changeRightsService = new ChangeExceptionLogRights(new ServiceConfig($rootPath)); 39 | $changeRightsService->init($request = new Request()); 40 | 41 | $this->assertTrue(file_exists($pathToExceptionLog)); 42 | $filePermissions = $this->getFilePermissions($pathToExceptionLog); 43 | $this->assertSame('0777', $filePermissions, 'Exception log should be writable.'); 44 | } 45 | 46 | /** 47 | * Return file permissions in a normal form. 48 | * 49 | * @param string $pathToFile 50 | * 51 | * @return string 52 | */ 53 | private function getFilePermissions($pathToFile) 54 | { 55 | return substr(sprintf('%o', fileperms($pathToFile)), -4); 56 | } 57 | } 58 | -------------------------------------------------------------------------------- /tests/Integration/Services/Files/FilesHelper.php: -------------------------------------------------------------------------------- 1 | url(); 30 | 31 | return $rootPath; 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /tests/Integration/Services/Files/RemoveTest.php: -------------------------------------------------------------------------------- 1 | getDirectoryStructure()); 18 | $this->initializeFilesRemoval($rootPath, []); 19 | $this->assertTrue(file_exists($rootPath.'/testDirectory/someFile.php'), "$rootPath/testDirectory/someFile.php"); 20 | $this->assertTrue(file_exists($rootPath.'/testDirectory/someFile2.php'), "$rootPath/testDirectory/someFile2.php"); 21 | } 22 | 23 | public function testRemoveFile() 24 | { 25 | $rootPath = FilesHelper::prepareStructureAndReturnPath($this->getDirectoryStructure()); 26 | $this->initializeFilesRemoval($rootPath, [$rootPath.'/testDirectory/someFile.php']); 27 | $this->assertFalse(file_exists($rootPath.'/testDirectory/someFile.php'), "$rootPath/testDirectory/someFile.php"); 28 | $this->assertTrue(file_exists($rootPath.'/testDirectory/someFile2.php'), "$rootPath/testDirectory/someFile2.php"); 29 | } 30 | 31 | /** 32 | * @param string $rootPath 33 | * @param array $files 34 | */ 35 | protected function initializeFilesRemoval($rootPath, $files) 36 | { 37 | $removeService = new Remove(new ServiceConfig($rootPath)); 38 | $request = new Request([Remove::FILES_PARAMETER_NAME => $files]); 39 | $removeService->init($request); 40 | } 41 | 42 | /** 43 | * Get directory structure to mock for the tests. 44 | * 45 | * @return array 46 | */ 47 | private function getDirectoryStructure() 48 | { 49 | return [ 50 | 'testDirectory' => [ 51 | 'someFile.php' => 'content', 52 | 'someFile2.php' => 'content', 53 | ] 54 | ]; 55 | } 56 | } 57 | -------------------------------------------------------------------------------- /tests/Integration/Services/Library/DatabaseDefaultsFileGeneratorTest.php: -------------------------------------------------------------------------------- 1 | getMockBuilder('OxidEsales\Eshop\Core\ConfigFile') 19 | ->disableOriginalConstructor() 20 | ->disableOriginalClone() 21 | ->getMock(); 22 | $configFile->dbUser = $user; 23 | $configFile->dbPwd = $password; 24 | $configFile->dbHost = $host; 25 | $configFile->dbPort = $port; 26 | $generator = new DatabaseDefaultsFileGenerator($configFile); 27 | $file = $generator->generate(); 28 | $fileContents = file_get_contents($file); 29 | 30 | $this->assertTrue((bool)strpos($fileContents, $user)); 31 | $this->assertTrue((bool)strpos($fileContents, $password)); 32 | $this->assertTrue((bool)strpos($fileContents, $host)); 33 | $this->assertTrue((bool)strpos($fileContents, $port)); 34 | 35 | unlink($file); 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /tests/Integration/Services/Library/ProjectConfigurationHandlerTest.php: -------------------------------------------------------------------------------- 1 | prepareVfsStructure(); 22 | } 23 | 24 | public function testFileBackup() 25 | { 26 | $projectConfigurationHelperStub = $this->makeProjectConfigurationHelperStub(); 27 | 28 | $handler = new ProjectConfigurationHandler($projectConfigurationHelperStub); 29 | $handler->backup(); 30 | 31 | $this->assertFileExists($this->getBackupConfigurationFile()); 32 | } 33 | 34 | public function testFolderBackupWithoutFile() 35 | { 36 | $projectConfigurationHelperStub = $this->makeProjectConfigurationHelperStub(); 37 | 38 | unlink($this->configurationFileInSubDirectory); 39 | $handler = new ProjectConfigurationHandler($projectConfigurationHelperStub); 40 | $handler->backup(); 41 | 42 | $this->assertDirectoryExists($this->getConfigurationBackupDirectory()); 43 | } 44 | 45 | public function testFileRestoration() 46 | { 47 | $projectConfigurationHelperStub = $this->makeProjectConfigurationHelperStub(); 48 | 49 | $handler = new ProjectConfigurationHandler($projectConfigurationHelperStub); 50 | $handler->backup(); 51 | unlink($this->configurationFileInSubDirectory); 52 | $handler->restore(); 53 | 54 | $this->assertFileExists($this->getBackupConfigurationFile()); 55 | } 56 | 57 | public function testFolderRestorationWhenItDoesNotExist() 58 | { 59 | $this->expectException(FileNotFoundException::class); 60 | 61 | $projectConfigurationHelperStub = $this->makeProjectConfigurationHelperStub(); 62 | 63 | $handler = new ProjectConfigurationHandler($projectConfigurationHelperStub); 64 | $handler->restore(); 65 | } 66 | 67 | private function prepareVfsStructure() 68 | { 69 | $structure = [ 70 | 'configuration' => [ 71 | 'shops' => [ 72 | 'configuration.yml' => 'anything', 73 | ] 74 | ], 75 | ]; 76 | 77 | $root = vfsStream::setup('root', null, $structure); 78 | 79 | $this->configurationDirectory = vfsStream::url('root/configuration'); 80 | $this->configurationFileInSubDirectory = vfsStream::url( 81 | 'root/configuration/shops/configuration.yml' 82 | ); 83 | } 84 | 85 | private function getBackupConfigurationFile() 86 | { 87 | return vfsStream::url( 88 | 'root/configuration-backup/shops/configuration.yml' 89 | ); 90 | } 91 | 92 | private function getConfigurationBackupDirectory() 93 | { 94 | return vfsStream::url( 95 | 'root/configuration-backup' 96 | ); 97 | } 98 | 99 | private function makeProjectConfigurationHelperStub(): ProjectConfigurationHelperInterface 100 | { 101 | $projectConfigurationHelperStub = $this->getMockBuilder(ProjectConfigurationHelperInterface::class) 102 | ->getMock(); 103 | 104 | $projectConfigurationHelperStub 105 | ->method('getConfigurationDirectoryPath') 106 | ->willReturn($this->configurationDirectory); 107 | 108 | return $projectConfigurationHelperStub; 109 | } 110 | } 111 | -------------------------------------------------------------------------------- /tests/Integration/Services/ShopInstaller/ShopInstallerTest.php: -------------------------------------------------------------------------------- 1 | checkBeforeInstall(); 22 | 23 | // to be able to assert afterwards, that the views generation was called, we delete one view here 24 | $this->dropOxDiscountView(); 25 | 26 | try { 27 | $serviceCaller = new ServiceCaller(new TestConfig()); 28 | 29 | $serviceCaller->callService('ShopInstaller'); 30 | } catch (\Exception $e) { 31 | exit("Failed to install shop with message:" . $e->getMessage()); 32 | } 33 | 34 | $this->checkAfterInstall(); 35 | } 36 | 37 | /** 38 | * To be able to assure, that the ShopInstall service call worked correct, we check before, if everything is well. 39 | */ 40 | protected function checkBeforeInstall() 41 | { 42 | $databaseHelper = new oxDatabaseHelper(DatabaseProvider::getDb()); 43 | $databaseHelper->adjustTemplateBlocksOxModuleColumn(); 44 | 45 | $this->assertThereExistsAtLeastOneDatabaseTable(); 46 | $this->assertOxModuleColumnHasMaxLength(self::DEFAULT_OXMODULE_COLUMN_MAX_LENGTH); 47 | $this->assureGenerateViewsWasCalled(); 48 | } 49 | 50 | /** 51 | * To assure, that the ShopInstall service call worked correct, we check, that 52 | * - the views are regenerated 53 | * - the migrations where called 54 | */ 55 | protected function checkAfterInstall() 56 | { 57 | $this->assureMigrationWasCalled(); 58 | $this->assureGenerateViewsWasCalled(); 59 | } 60 | 61 | /** 62 | * @param int $expectedMaxLength 63 | */ 64 | private function assertOxModuleColumnHasMaxLength($expectedMaxLength) 65 | { 66 | $databaseHelper = new oxDatabaseHelper(DatabaseProvider::getDb()); 67 | 68 | $columnInformation = $databaseHelper->getFieldInformation('oxtplblocks', 'OXMODULE'); 69 | 70 | $this->assertEquals($expectedMaxLength, $columnInformation->max_length); 71 | } 72 | 73 | protected function dropOxDiscountView() 74 | { 75 | $databaseHelper = new oxDatabaseHelper(DatabaseProvider::getDb()); 76 | 77 | $databaseHelper->dropView('oxdiscount'); 78 | 79 | $this->assertViewNotExists('oxdiscount'); 80 | } 81 | 82 | private function assureMigrationWasCalled() 83 | { 84 | $this->assertOxModuleColumnHasMaxLength(self::CHANGED_OXMODULE_COLUMN_MAX_LENGTH); 85 | } 86 | 87 | protected function assureGenerateViewsWasCalled() 88 | { 89 | $this->assertViewExists('oxdiscount'); 90 | } 91 | 92 | protected function assertThereExistsAtLeastOneDatabaseTable() 93 | { 94 | $databaseHelper = new oxDatabaseHelper(DatabaseProvider::getDb()); 95 | 96 | $this->assertNotEmpty($databaseHelper->getDataBaseTables()); 97 | } 98 | } 99 | -------------------------------------------------------------------------------- /tests/Integration/UnitTestCaseTest.php: -------------------------------------------------------------------------------- 1 | assertFalse($unitTestCase->getSessionParam($sessionKeyIsAdmin)); 37 | $this->assertSessionValueIsCorrect($unitTestCase, $sessionKeyIsAdmin); 38 | 39 | return $unitTestCase; 40 | } 41 | 42 | /** 43 | * Test, that the method 'setSessionParam' works as expected. 44 | */ 45 | public function testSetSessionParamWorks() 46 | { 47 | $unitTestCase = $this->testGetSessionParamWorks(); 48 | 49 | $sessionKeyIsAdmin = 'blIsAdmin'; 50 | $oldValue = $unitTestCase->getSessionParam($sessionKeyIsAdmin); 51 | 52 | $unitTestCase->setSessionParam($sessionKeyIsAdmin, !$oldValue); 53 | 54 | $expectedSessionParamOne = $unitTestCase->getSessionParam($sessionKeyIsAdmin); 55 | 56 | $unitTestCase->setSessionParam($sessionKeyIsAdmin, $oldValue); 57 | 58 | $expectedSessionParamTwo = $unitTestCase->getSessionParam($sessionKeyIsAdmin); 59 | 60 | $this->assertSame(!$oldValue, $expectedSessionParamOne); 61 | $this->assertSame($oldValue, $expectedSessionParamTwo); 62 | 63 | $this->assertSessionValueIsCorrect($unitTestCase, $sessionKeyIsAdmin); 64 | } 65 | 66 | /** 67 | * Test, that the method 'getRequestParameter' gives back an empty array, when nothing is put in before. 68 | */ 69 | public function testGetRequestParameterIsEmptyIfNothingIsSetBefore() 70 | { 71 | $unitTestCase = new testCase(); 72 | 73 | $requestParameter = $unitTestCase->getRequestParameter(''); 74 | 75 | $this->assertEmpty($requestParameter); 76 | $this->assertNull($requestParameter); 77 | } 78 | 79 | /** 80 | * Test, that the method 'getRequestParameter' gives back an empty array, when nothing is put in before. 81 | */ 82 | public function testSetRequestParameterWorks() 83 | { 84 | $unitTestCase = new testCase(); 85 | 86 | $parameterName = 'XYZ'; 87 | $parameterValue = 'ABC'; 88 | 89 | $oldRequestParameter = $unitTestCase->getRequestParameter($parameterName); 90 | 91 | $unitTestCase->setRequestParameter($parameterName, $parameterValue); 92 | 93 | $setRequestParameter = $unitTestCase->getRequestParameter($parameterName); 94 | 95 | $unitTestCase->setRequestParameter($parameterName, null); 96 | 97 | $afterRequestParameter = $unitTestCase->getRequestParameter($parameterName); 98 | 99 | $this->assertEmpty($oldRequestParameter); 100 | $this->assertNull($oldRequestParameter); 101 | 102 | $this->assertNotEmpty($setRequestParameter); 103 | $this->assertSame($parameterValue, $setRequestParameter); 104 | 105 | $this->assertEmpty($afterRequestParameter); 106 | $this->assertNull($afterRequestParameter); 107 | } 108 | 109 | /** 110 | * Test, that the method 'getConfigParam' works as expected. 111 | */ 112 | public function testGetConfigParamGivesBackCorrectValue() 113 | { 114 | $unitTestCase = new testCase(); 115 | 116 | $this->assertSame('0', $unitTestCase->getConfigParam('sDefaultLang')); 117 | } 118 | 119 | /** 120 | * Test, that the method 'setConfigParam' works as expected. 121 | */ 122 | public function testSetConfigParamSetsValueCorrect() 123 | { 124 | $unitTestCase = new testCase(); 125 | 126 | $newConfigValue = '12'; 127 | $oldConfigValue = $unitTestCase->getConfigParam('sDefaultLang'); 128 | 129 | $unitTestCase->setConfigParam('sDefaultLang', $newConfigValue); 130 | 131 | $setConfigValue = $unitTestCase->getConfigParam('sDefaultLang'); 132 | 133 | $unitTestCase->setConfigParam('sDefaultLang', $oldConfigValue); 134 | 135 | $afterConfigValue = $unitTestCase->getConfigParam('sDefaultLang'); 136 | 137 | $this->assertSame('0', $oldConfigValue); 138 | $this->assertSame($newConfigValue, $setConfigValue); 139 | $this->assertSame($oldConfigValue, $afterConfigValue); 140 | } 141 | 142 | /** 143 | * Test, that the method 'setAdminMode' works for the false case. 144 | */ 145 | public function testSetAdminModeFalseCase() 146 | { 147 | $unitTestCase = new testCase(); 148 | 149 | $oldAdminMode = $unitTestCase->getConfig()->isAdmin(); 150 | $oldSessionAdminMode = $_SESSION['blIsAdmin']; 151 | 152 | $unitTestCase->setAdminMode(false); 153 | 154 | $setSessionAdminMode = $unitTestCase->getSessionParam('blIsAdmin'); 155 | $setConfigAdminMode = $unitTestCase->getConfig()->isAdmin(); 156 | 157 | $unitTestCase->getConfig()->setAdminMode($oldAdminMode); 158 | $unitTestCase->setSessionParam($oldSessionAdminMode); 159 | 160 | $this->assertFalse($setConfigAdminMode); 161 | $this->assertFalse($setSessionAdminMode); 162 | } 163 | 164 | /** 165 | * Test, that the method 'setAdminMode' works for the true case. 166 | */ 167 | public function testSetAdminModeTrueCase() 168 | { 169 | $unitTestCase = new testCase(); 170 | 171 | $oldAdminMode = $unitTestCase->getConfig()->isAdmin(); 172 | $oldSessionAdminMode = $_SESSION['blIsAdmin']; 173 | 174 | $unitTestCase->setAdminMode(true); 175 | 176 | $setSessionAdminMode = $unitTestCase->getSessionParam('blIsAdmin'); 177 | $setConfigAdminMode = $unitTestCase->getConfig()->isAdmin(); 178 | 179 | $unitTestCase->getConfig()->setAdminMode($oldAdminMode); 180 | $unitTestCase->setSessionParam($oldSessionAdminMode); 181 | 182 | $this->assertTrue($setConfigAdminMode); 183 | $this->assertTrue($setSessionAdminMode); 184 | } 185 | 186 | /** 187 | * Ensure, that the session parameter, given by the method 'getSessionParam' is the same as the actual one in the $_SESSION. 188 | * 189 | * @param testCase $unitTestCase The object under test, we want to ensure to give us back the correct session value. 190 | * @param string $sessionKey The key of the session value we want to check. 191 | */ 192 | protected function assertSessionValueIsCorrect($unitTestCase, $sessionKey) 193 | { 194 | $this->assertSame($_SESSION[$sessionKey], $unitTestCase->getSessionParam($sessionKey)); 195 | } 196 | 197 | } 198 | -------------------------------------------------------------------------------- /tests/Integration/helpers/ExceptionLogFileHelperTest.php: -------------------------------------------------------------------------------- 1 | expectException( 24 | \OxidEsales\Eshop\Core\Exception\StandardException::class 25 | ); 26 | $this->expectExceptionMessage('Constructor parameter $exceptionLogFile must be a non empty string'); 27 | new \OxidEsales\TestingLibrary\helpers\ExceptionLogFileHelper($constructorParameters); 28 | } 29 | 30 | public function dataProviderWrongConstructorParameters() 31 | { 32 | return [ 33 | [''], 34 | [[]], 35 | [new \StdClass()], 36 | [false], 37 | [true], 38 | [1], 39 | [0], 40 | ]; 41 | } 42 | 43 | /** 44 | * @dataProvider dataProviderExpectedContent 45 | * @covers \OxidEsales\TestingLibrary\helpers\ExceptionLogFileHelper::getExceptionLogFileContent 46 | * 47 | * @throws \OxidEsales\Eshop\Core\Exception\StandardException 48 | */ 49 | public function testGetExceptionLogFileContentReturnsExpectedContent($expectedContent) 50 | { 51 | $exceptionLogFileResource = tmpfile(); 52 | $exceptionLogFile = stream_get_meta_data($exceptionLogFileResource)['uri']; 53 | fwrite($exceptionLogFileResource, $expectedContent); 54 | 55 | $exceptionLogFileHelper = new \OxidEsales\TestingLibrary\helpers\ExceptionLogFileHelper($exceptionLogFile); 56 | 57 | $actualContent = $exceptionLogFileHelper->getExceptionLogFileContent(); 58 | 59 | fclose($exceptionLogFileResource); 60 | 61 | $this->assertSame($expectedContent, $actualContent); 62 | } 63 | 64 | public function dataProviderExpectedContent() 65 | { 66 | return [ 67 | [''], 68 | ['test'], 69 | ['tèßt'], 70 | [" 71 | 72 | test 73 | 74 | "] 75 | ]; 76 | } 77 | 78 | /** 79 | * @covers \OxidEsales\TestingLibrary\helpers\ExceptionLogFileHelper::clearExceptionLogFile 80 | */ 81 | public function testClearExceptionLogFileThrowsExceptionOnFileNotWritable() 82 | { 83 | $exceptionLogFileRessource = tmpfile(); 84 | fwrite($exceptionLogFileRessource, 'test'); 85 | $exceptionLogFile = stream_get_meta_data($exceptionLogFileRessource)['uri']; 86 | 87 | $expectedExceptionMessage = 'File ' . $exceptionLogFile . ' could not be opened in write mode'; 88 | 89 | $exceptionLogFileHelper = new \OxidEsales\TestingLibrary\helpers\ExceptionLogFileHelper($exceptionLogFile); 90 | chmod($exceptionLogFile, 0444); 91 | $this->assertFalse(is_writable($exceptionLogFile)); 92 | 93 | $actualExceptionMessage = ''; 94 | $exceptionThrown = false; 95 | try { 96 | // We do not want the E_WARNING issued by file_get_contents to break our test 97 | $originalErrorReportingLevel = error_reporting(); 98 | error_reporting($originalErrorReportingLevel & ~E_WARNING); 99 | $exceptionLogFileHelper->clearExceptionLogFile(); 100 | } catch (\OxidEsales\Eshop\Core\Exception\StandardException $actualException) { 101 | $actualExceptionMessage = $actualException->getMessage(); 102 | $exceptionThrown = true; 103 | } finally { 104 | error_reporting($originalErrorReportingLevel); 105 | fclose($exceptionLogFileRessource); 106 | } 107 | 108 | $this->assertEquals($expectedExceptionMessage, $actualExceptionMessage); 109 | $this->assertTrue($exceptionThrown); 110 | } 111 | 112 | /** 113 | * @covers \OxidEsales\TestingLibrary\helpers\ExceptionLogFileHelper::clearExceptionLogFile 114 | * 115 | * @throws \OxidEsales\Eshop\Core\Exception\StandardException 116 | */ 117 | public function testClearExceptionLogFileDeletesExceptionLogFileContent() 118 | { 119 | $exceptionLogFileRessource = tmpfile(); 120 | fwrite($exceptionLogFileRessource, 'test'); 121 | $exceptionLogFile = stream_get_meta_data($exceptionLogFileRessource)['uri']; 122 | 123 | $exceptionLogFileHelper = new \OxidEsales\TestingLibrary\helpers\ExceptionLogFileHelper($exceptionLogFile); 124 | $exceptionLogFileHelper->clearExceptionLogFile(); 125 | 126 | $actualContent = $exceptionLogFileHelper->getExceptionLogFileContent(); 127 | 128 | fclose($exceptionLogFileRessource); 129 | 130 | $this->assertEmpty($actualContent); 131 | } 132 | 133 | /** 134 | * @dataProvider dataProviderNumberOfExceptionsToBeLogged 135 | * @covers \OxidEsales\TestingLibrary\helpers\ExceptionLogFileHelper::getParsedExceptions 136 | * 137 | * @throws \OxidEsales\Eshop\Core\Exception\StandardException 138 | */ 139 | public function testGetParsedExceptionsReturnsExpectedValue($exceptionsToBeLogged) 140 | { 141 | $expectedLevel = 'ERROR'; 142 | $expectedType = \Exception::class; 143 | $expectedMessage = 'test message'; 144 | 145 | $exception = new \Exception($expectedMessage); 146 | 147 | $exceptionLogFileRessource = tmpfile(); 148 | $exceptionLogFile = stream_get_meta_data($exceptionLogFileRessource)['uri']; 149 | 150 | $lineFormatter = new LineFormatter(); 151 | $lineFormatter->includeStacktraces(true); 152 | 153 | $streamHandler = new StreamHandler( 154 | $exceptionLogFile, 155 | 'error' 156 | ); 157 | $streamHandler->setFormatter($lineFormatter); 158 | 159 | $logger = new Logger('test logger'); 160 | $logger->pushHandler($streamHandler); 161 | 162 | for ($i = 0; $i < $exceptionsToBeLogged; $i++) { 163 | $logger->error($exception->getMessage(), [$exception]); 164 | } 165 | 166 | $exceptionLogFileHelper = new \OxidEsales\TestingLibrary\helpers\ExceptionLogFileHelper($exceptionLogFile); 167 | $actualParsedExceptions = $exceptionLogFileHelper->getParsedExceptions(); 168 | 169 | fclose($exceptionLogFileRessource); 170 | 171 | for ($i = 0; $i < $exceptionsToBeLogged; $i++) { 172 | $this->assertContains($expectedLevel, $actualParsedExceptions[$i]); 173 | $this->assertContains($expectedType, $actualParsedExceptions[$i]); 174 | $this->assertContains($expectedMessage, $actualParsedExceptions[$i]); 175 | } 176 | } 177 | 178 | public function dataProviderNumberOfExceptionsToBeLogged() 179 | { 180 | return [ 181 | [0], 182 | [1], 183 | [5], 184 | ]; 185 | } 186 | } 187 | -------------------------------------------------------------------------------- /tests/bootstrap.php: -------------------------------------------------------------------------------- 1 | getShopPath() . '/vendor/autoload.php'; -------------------------------------------------------------------------------- /tests/phpunit.xml: -------------------------------------------------------------------------------- 1 | 19 | -------------------------------------------------------------------------------- /tests/unit/FileCopierTest.php: -------------------------------------------------------------------------------- 1 | getMockBuilder('\OxidEsales\TestingLibrary\FileCopier') 18 | ->setMethods(['executeCommand']) 19 | ->getMock(); 20 | $fileCopier->expects($this->once())->method('executeCommand')->with($this->equalTo($expectedCommand)); 21 | 22 | $fileCopier->copyFiles('source', 'target'); 23 | } 24 | 25 | public function testCopyLocalFileWithPermissions() 26 | { 27 | $expectedCommand = "cp -frT 'source' 'target' && chmod 777 'target'"; 28 | 29 | /** @var FileCopier|PHPUnit\Framework\MockObject\MockObject $fileCopier */ 30 | $fileCopier = $this->getMockBuilder('\OxidEsales\TestingLibrary\FileCopier') 31 | ->setMethods(['executeCommand']) 32 | ->getMock(); 33 | $fileCopier->expects($this->once())->method('executeCommand')->with($this->equalTo($expectedCommand)); 34 | 35 | $fileCopier->copyFiles('source', 'target', true); 36 | } 37 | 38 | public function testCopyRemoteFile() 39 | { 40 | $expectedCommand = "scp -rp 'source' 'user@host:/target'"; 41 | 42 | /** @var FileCopier|PHPUnit\Framework\MockObject\MockObject $fileCopier */ 43 | $fileCopier = $this->getMockBuilder('\OxidEsales\TestingLibrary\FileCopier') 44 | ->setMethods(['executeCommand']) 45 | ->getMock(); 46 | $fileCopier->expects($this->once())->method('executeCommand')->with($this->equalTo($expectedCommand)); 47 | 48 | $fileCopier->copyFiles('source', 'user@host:/target'); 49 | } 50 | 51 | public function testCopyRemoteFileWithPermissions() 52 | { 53 | $expectedCommand = "rsync -rp --perms --chmod=u+rwx,g+rwx,o+rwx 'source' 'user@host:/target'"; 54 | 55 | /** @var FileCopier|PHPUnit\Framework\MockObject\MockObject $fileCopier */ 56 | $fileCopier = $this->getMockBuilder('\OxidEsales\TestingLibrary\FileCopier') 57 | ->setMethods(array('executeCommand')) 58 | ->getMock(); 59 | $fileCopier->expects($this->once())->method('executeCommand')->with($this->equalTo($expectedCommand)); 60 | 61 | $fileCopier->copyFiles('source', 'user@host:/target', true); 62 | } 63 | 64 | public function testEmptyDirectoryCreationWhenDirectoryDoesNotExist() 65 | { 66 | $structure = array( 67 | 'testDirectory' => array() 68 | ); 69 | 70 | vfsStream::setup('root', 777, $structure); 71 | 72 | $newDirectory = vfsStream::url('root/testDirectory/emptyDirectory'); 73 | 74 | $fileCopier = new FileCopier(); 75 | $fileCopier->createEmptyDirectory($newDirectory); 76 | 77 | $this->assertTrue(is_dir($newDirectory)); 78 | $this->assertEquals(2, count(scandir($newDirectory))); 79 | } 80 | 81 | public function testEmptyDirectoryCreationWhenDirectoryExist() 82 | { 83 | $structure = array( 84 | 'testDirectory' => array( 85 | 'nonEmptyDirectory' => array( 86 | 'someFile.php' => 'content', 87 | 'someFile2.php' => 'content', 88 | 'directory' => array( 89 | 'someFile' => 'content' 90 | ) 91 | ) 92 | ) 93 | ); 94 | 95 | vfsStream::setup('root', 777, $structure); 96 | 97 | $newDirectory = vfsStream::url('root/testDirectory/nonEmptyDirectory'); 98 | 99 | $fileCopier = new FileCopier(); 100 | $fileCopier->createEmptyDirectory($newDirectory); 101 | 102 | $this->assertTrue(is_dir($newDirectory)); 103 | $this->assertEquals(2, count(scandir($newDirectory))); 104 | } 105 | } 106 | -------------------------------------------------------------------------------- /tests/unit/Services/Library/ServiceConfigTest.php: -------------------------------------------------------------------------------- 1 | assertEquals('/path/to/shop/', $config->getShopDirectory()); 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /tests/unit/Services/ServiceFactoryTest.php: -------------------------------------------------------------------------------- 1 | expectException('Exception'); 17 | $message = "Service 'TestService' was not found!"; 18 | $this->expectExceptionMessage($message); 19 | 20 | vfsStream::setup('root', 777, array('bootstrap.php' => '')); 21 | 22 | /** @var ServiceConfig|PHPUnit\Framework\MockObject\MockObject $config */ 23 | $config = $this->getMockBuilder(OxidEsales\TestingLibrary\Services\Library\ServiceConfig::class) 24 | ->setMethods(['getServicesDirectory', 'getShopDirectory']) 25 | ->disableOriginalConstructor() 26 | ->getMock(); 27 | $config->expects($this->any())->method('getServicesDirectory')->will($this->returnValue(vfsStream::url('root'))); 28 | $config->expects($this->any())->method('getShopDirectory')->will($this->returnValue(vfsStream::url('root'))); 29 | 30 | $serviceFactory = new ServiceFactory($config); 31 | $serviceFactory->createService('TestService'); 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /tests/unit/TestConfigTest.php: -------------------------------------------------------------------------------- 1 | buildModuleStructureWithTwoModules(); 27 | 28 | $testConfig = $this->getMockBuilder('\OxidEsales\TestingLibrary\TestConfig')->setMethods([ 29 | 'shouldRunModuleTests', 30 | 'getPartialModulePaths', 31 | 'getShopPath' 32 | 33 | ])->getMock(); 34 | $testConfig->expects($this->any())->method('shouldRunModuleTests')->will($this->returnValue(true)); 35 | $testConfig->expects($this->any())->method('getPartialModulePaths')->will( 36 | $this->returnValue( 37 | [ 38 | 'myvendor/namespacedModule', 39 | 'myvendor/plainModule' 40 | ] 41 | ) 42 | ); 43 | 44 | $shopPath = vfsStream::url('root/'); 45 | $testConfig->expects($this->any())->method('getShopPath')->will($this->returnValue($shopPath)); 46 | 47 | $this->assertEquals( 48 | [ 49 | vfsStream::url('root/modules/myvendor/namespacedModule/Tests/'), 50 | vfsStream::url('root/modules/myvendor/plainModule/tests/') 51 | ], 52 | $testConfig->getModuleTestSuites(), 53 | "Directories for modules test suites are not found properly." 54 | 55 | ); 56 | } 57 | 58 | private function buildModuleStructureWithTwoModules() 59 | { 60 | $structure = [ 61 | 'modules' => [ 62 | 'myvendor' => [ 63 | 'namespacedModule' => [ 64 | 'Tests' => [ 65 | 'Acceptance' 66 | ] 67 | ], 68 | 'plainModule' => [ 69 | 'tests' => [ 70 | 'Acceptance' 71 | ] 72 | ] 73 | ] 74 | ] 75 | ]; 76 | vfsStream::setup('root', null, $structure); 77 | } 78 | 79 | } -------------------------------------------------------------------------------- /tests/unit/TestSqlPathProviderTest.php: -------------------------------------------------------------------------------- 1 | createMock(EditionSelector::class); 25 | $editionSelectorMock->method('isEnterprise') 26 | ->willReturn($edition === EditionSelector::ENTERPRISE); 27 | $testDataPathProvider = new TestSqlPathProvider($editionSelectorMock, $shopPath); 28 | 29 | $datPath = $testDataPathProvider->getDataPathBySuitePath($testSuitePath); 30 | 31 | $this->assertSame($resultPath, $datPath); 32 | } 33 | 34 | public function providerChecksForCorrectPath(): array 35 | { 36 | return [ 37 | [ 38 | '/var/www/vendor/oxid-esales/tests-deprecated-ee/Acceptance/Admin', 39 | EditionSelector::ENTERPRISE, 40 | '/var/www/vendor/oxid-esales/tests-deprecated-ee/Acceptance/Admin/testSql' 41 | ], 42 | [ 43 | '/var/www/vendor/oxid-esales/tests-deprecated-ee/Acceptance/Frontend', 44 | EditionSelector::ENTERPRISE, 45 | '/var/www/vendor/oxid-esales/tests-deprecated-ee/Acceptance/Frontend/testSql' 46 | ], 47 | [ 48 | '/var/www/vendor/oxid-esales/tests-deprecated-ce/Acceptance/Admin', 49 | EditionSelector::COMMUNITY, 50 | '/var/www/vendor/oxid-esales/tests-deprecated-ce/Acceptance/Admin/testSql' 51 | ], 52 | [ 53 | '/var/www/vendor/oxid-esales/tests-deprecated-pe/Acceptance/Admin', 54 | EditionSelector::PROFESSIONAL, 55 | '/var/www/vendor/oxid-esales/tests-deprecated-pe/Acceptance/Admin/testSql' 56 | ], 57 | ]; 58 | } 59 | } 60 | -------------------------------------------------------------------------------- /tests/unit/UnitTestCaseTest.php: -------------------------------------------------------------------------------- 1 | assertEmpty($unitTestCase->getTeardownSqls()); 32 | } 33 | 34 | /** 35 | * Test, that the method addTearDownSql adds one sql correct. 36 | */ 37 | public function testAddTearDownSqlLeadsToTheCorrectSqlArray() 38 | { 39 | $unitTestCase = new testCase(); 40 | 41 | $sql = 'SELECT * FROM oxarticles;'; 42 | 43 | $unitTestCase->addTeardownSql($sql); 44 | 45 | $this->assertSame([$sql], $unitTestCase->getTeardownSqls()); 46 | } 47 | 48 | /** 49 | * Test, that the method addTearDownSql adds the same sql only once. 50 | */ 51 | public function testAddTearDownSqlDoesntAddsTheSameSqlTwoTimes() 52 | { 53 | $unitTestCase = new testCase(); 54 | 55 | $sql = 'SELECT * FROM oxarticles;'; 56 | 57 | $unitTestCase->addTeardownSql($sql); 58 | $unitTestCase->addTeardownSql($sql); 59 | 60 | $this->assertSame([$sql], $unitTestCase->getTeardownSqls()); 61 | } 62 | 63 | /** 64 | * Test, that the method addTearDownSql adds multiple sqls correct. 65 | */ 66 | public function testAddTearDownSqlAddsMultipleSqlsCorrect() 67 | { 68 | $unitTestCase = new testCase(); 69 | 70 | $sqlOne = 'SELECT * FROM oxarticles;'; 71 | $sqlTwo = "INSERT INTO oxarticles(OXID) VALUES('EXAMPLE_OXID');"; 72 | $sqlThree = "UPDATE oxarticles SET OXTITLE='EXAMPLE_TITLE' WHERE OXID='EXAMPLE_OXID';"; 73 | 74 | $unitTestCase->addTeardownSql($sqlOne); 75 | $unitTestCase->addTeardownSql($sqlTwo); 76 | $unitTestCase->addTeardownSql($sqlThree); 77 | $unitTestCase->addTeardownSql($sqlTwo); 78 | 79 | $this->assertSame([$sqlOne, $sqlTwo, $sqlThree], $unitTestCase->getTeardownSqls()); 80 | } 81 | 82 | /** 83 | * Test, that the method getTablesForCleanup returns an empty array after creation. 84 | */ 85 | public function testGetTableForCleanup() 86 | { 87 | $unitTestCase = new testCase(); 88 | 89 | $this->assertEmpty($unitTestCase->getTablesForCleanup()); 90 | } 91 | 92 | /** 93 | * Test, that the method addTablesForCleanup adds one table name correct. 94 | */ 95 | public function testAddTableForCleanupAddsOneTableNameCorrect() 96 | { 97 | $unitTestCase = new testCase(); 98 | 99 | $tableName = 'oxcount'; 100 | 101 | $unitTestCase->addTableForCleanup($tableName); 102 | 103 | $this->assertNotEmpty($unitTestCase->getTablesForCleanup()); 104 | $this->assertSame([$tableName], $unitTestCase->getTablesForCleanup()); 105 | } 106 | 107 | /** 108 | * Test, that the method addTablesForCleanup adds one table name not a second time. 109 | */ 110 | public function testAddTableForCleanupAddsOneTableNameOnlyOnce() 111 | { 112 | $unitTestCase = new testCase(); 113 | 114 | $tableName = 'oxcount'; 115 | 116 | $unitTestCase->addTableForCleanup($tableName); 117 | $unitTestCase->addTableForCleanup($tableName); 118 | 119 | $this->assertNotEmpty($unitTestCase->getTablesForCleanup()); 120 | $this->assertSame([$tableName], $unitTestCase->getTablesForCleanup()); 121 | } 122 | 123 | /** 124 | * Test, that the method addTablesForCleanup adds a multi table name and it. 125 | */ 126 | public function testAddTableForCleanupAddsTheMultiShopTablesCorrect() 127 | { 128 | $unitTestCase = new testCase(); 129 | 130 | $tableName = 'oxarticles'; 131 | $tableNameToShop = 'oxarticles2shop'; 132 | 133 | $unitTestCase->addTableForCleanup($tableName); 134 | 135 | $this->assertNotEmpty($unitTestCase->getTablesForCleanup()); 136 | if ('EE' === $this->getTestConfig()->getShopEdition()) { 137 | $this->assertSame([$tableName, $tableNameToShop], $unitTestCase->getTablesForCleanup()); 138 | } else { 139 | $this->assertSame([$tableName], $unitTestCase->getTablesForCleanup()); 140 | } 141 | } 142 | 143 | } 144 | -------------------------------------------------------------------------------- /tests/unit/VfsStreamWrapperTest.php: -------------------------------------------------------------------------------- 1 | assertInstanceOf('\org\bovigo\vfs\vfsStreamDirectory', $vfsStreamWrapper->getRoot()); 16 | } 17 | 18 | public function testReturningTheSameRootOnEveryCall() 19 | { 20 | $vfsStreamWrapper = new VfsStreamWrapper(); 21 | $root = $vfsStreamWrapper->getRoot(); 22 | 23 | $this->assertSame($root, $vfsStreamWrapper->getRoot()); 24 | } 25 | 26 | public function testReturningCorrectRootPath() 27 | { 28 | $vfsStreamWrapper = new VfsStreamWrapper(); 29 | 30 | $this->assertEquals('vfs://root/', $vfsStreamWrapper->getRootPath()); 31 | } 32 | 33 | public function testFileCreation() 34 | { 35 | $vfsStreamWrapper = new VfsStreamWrapper(); 36 | $filePath = $vfsStreamWrapper->createFile('testFile.txt', 'content'); 37 | 38 | $this->assertTrue(file_exists($filePath)); 39 | $this->assertEquals('content', file_get_contents($filePath)); 40 | } 41 | 42 | public function providerCreateFile() 43 | { 44 | return array( 45 | array('path'), 46 | array('path/to/file'), 47 | array('/path/to/file') 48 | ); 49 | } 50 | 51 | /** 52 | * @dataProvider providerCreateFile 53 | * 54 | * @param string $directory 55 | */ 56 | public function testCreateFile($directory) 57 | { 58 | $vfsStream = new VfsStreamWrapper(); 59 | $file = $vfsStream->createFile($directory .'/testFile.txt', 'content'); 60 | $rootPath = $vfsStream->getRootPath(); 61 | 62 | $this->assertEquals($rootPath . $directory .'/testFile.txt', $file); 63 | $this->assertTrue(is_dir($rootPath . $directory)); 64 | $this->assertFileExists($file); 65 | } 66 | 67 | public function testCreateFileWithNumericContent() 68 | { 69 | $vfsStream = new VfsStreamWrapper(); 70 | $file = $vfsStream->createFile('testFile.txt', 1234); 71 | 72 | $this->assertStringEqualsFile($file, '1234'); 73 | } 74 | 75 | public function testCreatingMultipleFiles() 76 | { 77 | $vfsStreamWrapper = new VfsStreamWrapper(); 78 | $file1 = $vfsStreamWrapper->createFile('testFile1.txt', 'content1'); 79 | $file2 = $vfsStreamWrapper->createFile('testFile2.txt', 'content2'); 80 | 81 | $this->assertTrue(file_exists($file1)); 82 | $this->assertEquals('content1', file_get_contents($file1)); 83 | $this->assertTrue(file_exists($file2)); 84 | $this->assertEquals('content2', file_get_contents($file2)); 85 | } 86 | 87 | public function testStructureCreation() 88 | { 89 | $structure = array( 90 | 'dir' => array( 91 | 'subdir' => array( 92 | 'testFile' => 'content' 93 | ) 94 | ), 95 | 'dir2' => array( 96 | 'subdir2' => array( 97 | 'testFile2' => 'content' 98 | ) 99 | ) 100 | ); 101 | 102 | $vfsStreamWrapper = new VfsStreamWrapper(); 103 | 104 | $vfsStreamWrapper->createStructure($structure); 105 | $rootPath = $vfsStreamWrapper->getRootPath(); 106 | 107 | $this->assertTrue(is_dir($rootPath .'dir')); 108 | $this->assertTrue(is_dir($rootPath .'dir/subdir')); 109 | $this->assertEquals('content', file_get_contents($rootPath .'dir/subdir/testFile')); 110 | } 111 | 112 | public function testStructureCreationWithPathsSpecified() 113 | { 114 | $structure = array( 115 | 'dir/subdir/testFile' => 'content', 116 | 'dir2/subdir/testFile' => 'content2', 117 | 'dir3/subdir3/testFile3' => 'content3', 118 | 'dir4' => [ 119 | 'subdir4/testFile4' => 'content4', 120 | ] 121 | ); 122 | 123 | $vfsStreamWrapper = new VfsStreamWrapper(); 124 | 125 | $vfsStreamWrapper->createStructure($structure); 126 | $rootPath = $vfsStreamWrapper->getRootPath(); 127 | 128 | $this->assertEquals('content', file_get_contents($rootPath .'dir/subdir/testFile')); 129 | $this->assertEquals('content2', file_get_contents($rootPath .'dir2/subdir/testFile')); 130 | $this->assertEquals('content3', file_get_contents($rootPath .'dir3/subdir3/testFile3')); 131 | $this->assertEquals('content4', file_get_contents($rootPath .'dir4/subdir4/testFile4')); 132 | } 133 | 134 | public function testReturningRootDirectoryAfterStructureCreation() 135 | { 136 | $structure = array(); 137 | 138 | $vfsStreamWrapper = new VfsStreamWrapper(); 139 | 140 | $returnedPath = $vfsStreamWrapper->createStructure($structure); 141 | $expectedPath = $vfsStreamWrapper->getRootPath(); 142 | 143 | $this->assertEquals($returnedPath, $expectedPath); 144 | } 145 | } 146 | -------------------------------------------------------------------------------- /workflow.puml: -------------------------------------------------------------------------------- 1 | @startuml 2 | start 3 | 4 | if ( Configuration option 5 | restore_shop_after_tests_suite 6 | is set to true) 7 | :Dump database: Dump-1; 8 | else (no) 9 | endif; 10 | 11 | :Install Shop; 12 | 13 | if (Is this acceptance tests?) 14 | :Install demo data; 15 | else (no, this is unit tests) 16 | :Do not install demodata; 17 | endif 18 | 19 | :Dump database: Dump-2; 20 | 21 | while (Run all test suits) 22 | 23 | :Run suit; 24 | 25 | :Add data for test suit: 26 | testData 27 | testSql; 28 | 29 | if ( module_ids 30 | has module configured?) 31 | :Activate the module; 32 | endif; 33 | 34 | :Dump database: Dump-3; 35 | 36 | while (Run all tests) 37 | 38 | :Run test; 39 | 40 | if (Is this acceptance test suit?) 41 | :Restore database to Dump-3; 42 | else (no, this is unit test suit) 43 | endif 44 | 45 | if (This is the last test in test file?) 46 | :Restore database to Dump-3; 47 | else (no) 48 | endif 49 | 50 | endwhile 51 | 52 | :Restore database to Dump-2; 53 | 54 | endwhile 55 | 56 | if (restore_shop_after_tests_suite is set to true) 57 | :Restore database to Dump-1; 58 | else (no) 59 | endif; 60 | 61 | stop 62 | 63 | @enduml 64 | --------------------------------------------------------------------------------