getTestResultObject()->stopOnError(true); $this->getTestResultObject()->stopOnFailure(true); $this->restoreDefaultConfig(); $this->restoreDefaultSettings(); $this->restoreDefaultCtrl(); $this->restoreDefaultLanguage(); // Clear caches $this->clearCaches(); // Clear cache by generating new BUILD_ID for each test static $iteration = 0; $iteration++; $db = TEST_DB_NAME; putenv("BUILD_ID={$db}_{$iteration}"); $this->suspendLogging(true); $this->assertSame(0, sqlGetConnection()->getTransactionNestingLevel(), 'The test itself must not be in a transaction.'); sqlStartTransaction(); $this->transactionActivated = true; $this->setTestDefaults(); $this->suspendLogging(false); $this->updateModules(); parent::setUp(); // todo find how to restore previous values, not force false. This unfortunately overrides respective cli flags $this->getTestResultObject()->stopOnError(false); $this->getTestResultObject()->stopOnFailure(false); } protected function tearDown(): void { parent::tearDown(); $this->suspendLogging(true); $this->assertSameTransactionLevel(); sqlRollbackTransaction(); $this->assertNoChangesLeftInDatabase(); $this->suspendLogging(false); $this->tearDownContainer(); // Reverting sql_mode // sqlQuery("SET sql_mode = 'NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION'"); } public function addModule($module, $submodule = null, $restartContainer = false) { $cfg = \KupShop\KupShopBundle\Config::get(); if ($submodule) { if (is_array($cfg['Modules'][$module])) { $cfg['Modules'][$module][$submodule] = true; } else { $cfg['Modules'][$module] = [$submodule => true]; } } else { $cfg['Modules'][$module] = true; } if ($restartContainer) { $this->tearDownContainer(); // Nemelo by byt třeba spouštět, všechny migrace proběhnou na začátku díky config.test.php // $this->createSchema(); } } public function removeModule($module, $submodule = null) { $cfg = \KupShop\KupShopBundle\Config::get(); if ($submodule) { $cfg['Modules'][$module][$submodule] = false; } else { $cfg['Modules'][$module] = false; } } /** * Returns the test database connection. * * @return \PHPUnit\DbUnit\Database\DefaultConnection */ public function getConnection() { return new \PHPUnit\DbUnit\Database\DefaultConnection(sqlGetConnection()->getWrappedConnection()); } /** * Returns the test dataset. * * @return \PHPUnit\DbUnit\DataSet\DefaultDataSet */ protected function getDataSet() { return new \PHPUnit\DbUnit\DataSet\DefaultDataSet(); } /** * Returns the database operation executed in test setup. * * @return \PHPUnit\DbUnit\Operation\Composite */ protected function getSetUpOperation() { return new \PHPUnit\DbUnit\Operation\Composite([ new \PHPUnit\DbUnit\Operation\DeleteAll(), new \PHPUnit\DbUnit\Operation\Insert(), ]); } public function skipIfNoModule($moduleName) { if (!findModule($moduleName)) { $this->markTestSkipped("Module '{$moduleName}' is disabled"); } } protected function suspendLogging($suspend) { static $logger = null; if ($suspend) { $this->assertNull($logger); // Suspend SQL logging $logger = sqlGetConnection()->getConfiguration()->getSQLLogger(); sqlGetConnection()->getConfiguration()->setSQLLogger(null); } else { // Resume SQL logging sqlGetConnection()->getConfiguration()->setSQLLogger($logger); $logger = null; } } private function restoreDefaultLanguage() { global $txt_str; if (is_null(self::$txt_str)) { self::$txt_str = $txt_str; } $txt_str = self::$txt_str; } private function restoreDefaultConfig() { global $cfg; if (is_null(self::$cfg)) { self::$cfg = Config::get()->getContainer(); } $cfg = self::$cfg; } protected function restoreDefaultCtrl() { global $ctrl; $defaults = [ 'id' => 0, 'admin' => 0, 'logged' => false, 'user_key' => '123456test123456', 'currency' => 'CZK', 'currUrl' => [ 'Abs' => '', 'Rel' => '', ], ]; $ctrl = ServiceContainer::getService(\KupShop\KupShopBundle\Util\Compat\CtrlLoader::class); $ctrl->setContainer($defaults); return $ctrl; } private function restoreDefaultSettings() { global $dbcfg; if (is_null(self::$dbcfg)) { self::$dbcfg = Settings::getDefault(); } $dbcfg = clone self::$dbcfg; Settings::setDefault(['cs' => $dbcfg]); } protected function getContextManager() { if (!isset($this->contextManager)) { $this->contextManager = ServiceContainer::getService(ContextManager::class); } return $this->contextManager; } private function setTestDefaults() { Cart::setCartID('123456'); $this->getContextManager()->forceEmptyContexts(); } private function assertSameTransactionLevel() { $transactionLevel = sqlGetConnection()->getTransactionNestingLevel(); if ($this->transactionActivated && 1 !== $transactionLevel) { $this->getTestResultObject()->stop(); $this->getTestResultObject()->addError( $this, new Exception($this->getTestMethodName().": The tested code ended up in a different transaction level ({$transactionLevel}) than it started in (1). Maybe missing parent::setUp() ?"), 0 ); } } private function assertNoChangesLeftInDatabase() { global $db; if (!$db->checkDatabaseNotChanged()) { $this->getTestResultObject()->stop(); $this->getTestResultObject()->addError( $this, new Exception($this->getTestMethodName().': Test left behind changes in the database.'), 0 ); } } /** * Returns the dataset from JSON-encoded string. * * @param $string string JSON-encoded dataset * * @return \PHPUnit\DbUnit\DataSet\ArrayDataSet */ protected function getJsonDataSet($string) { return new \PHPUnit\DbUnit\DataSet\ArrayDataSet(json_decode_strict($string, true)); } /** * Returns the dataset from JSON file. * * @param $file string|null file name to load data from. Can be absolute, relative to test or null to use .json * * @return \PHPUnit\DbUnit\DataSet\ArrayDataSet */ protected function getJsonDataSetFromFile($file = null) { if ($file === null || !file_exists($file)) { $classFile = (new ReflectionClass($this))->getFileName(); if ($file) { $file = dirname($classFile).'/'.$file; } else { $file = str_replace('.php', '.json', $classFile); } } return $this->getJsonDataSet(file_get_contents($file)); } public function getTestMethodName() { return get_class($this).'::'.$this->getName(); } protected function clearCaches() { Delivery::clearCache(); $this->get(\KupShop\CatalogBundle\Section\SectionTree::class)->clearCache(); Contexts::clear(); getLocalCache()->clear(); } protected function updateModules() { } public function initializeRequestStack(): void { ServiceContainer::getService('request_stack')->push(Request::createFromGlobals()); } protected function switchLanguage($language = 'sk') { /** @var \KupShop\KupShopBundle\Context\LanguageContext $languageContext */ $languageContext = Contexts::get(\KupShop\KupShopBundle\Context\LanguageContext::class); $languageContext->activate($language); global $txt_str; $translator = $this->get(\KupShop\KupShopBundle\Util\Locale\PHPArrayTranslator::class); $txt_str = $translator->loadShopMainTranslations(); } }