芝麻web文件管理V1.00
编辑当前文件:/home2/sdektunc/xmintal-back/vendor/codeception/module-yii2/src/Codeception/Module/Yii2.php
haveFixtures(['posts' => PostsFixture::className()]); * ``` * * or, if you need to load fixtures before the test, you * can specify fixtures in the `_fixtures` method of a test case: * * ```php * PostsFixture::className()] * } * ``` * * ## URL * * With this module you can also use Yii2's URL format for all codeception * commands that expect a URL: * * ```php * amOnPage(['site/view','page'=>'about']); * $I->amOnPage('index-test.php?site/index'); * $I->amOnPage('http://localhost/index-test.php?site/index'); * $I->sendAjaxPostRequest(['/user/update', 'id' => 1], ['UserForm[name]' => 'G.Hopper']); * ``` * * ## Status * * Maintainer: **samdark** * Stability: **stable** * * @property \Codeception\Lib\Connector\Yii2 $client */ class Yii2 extends Framework implements ActiveRecord, MultiSession, PartedModule { /** * Application config file must be set. * @var array */ protected $config = [ 'fixturesMethod' => '_fixtures', 'cleanup' => true, 'ignoreCollidingDSN' => false, 'transaction' => true, 'entryScript' => '', 'entryUrl' => 'http://localhost/index-test.php', 'responseCleanMethod' => Yii2Connector::CLEAN_CLEAR, 'requestCleanMethod' => Yii2Connector::CLEAN_RECREATE, 'recreateComponents' => [], 'recreateApplication' => false, 'closeSessionOnRecreateApplication' => true, 'applicationClass' => null, ]; protected $requiredFields = ['configFile']; /** * @var Yii2Connector\FixturesStore[] */ public $loadedFixtures = []; /** * Helper to manage database connections * @var Yii2Connector\ConnectionWatcher */ private $connectionWatcher; /** * Helper to force database transaction * @var Yii2Connector\TransactionForcer */ private $transactionForcer; /** * @var array The contents of $_SERVER upon initialization of this object. * This is only used to restore it upon object destruction. * It MUST not be used anywhere else. */ private $server; public function _initialize() { if ($this->config['transaction'] === null) { $this->config['transaction'] = $this->backupConfig['transaction'] = $this->config['cleanup']; } $this->defineConstants(); $this->server = $_SERVER; $this->initServerGlobal(); } /** * Module configuration changed inside a test. * We always re-create the application. */ protected function onReconfigure() { parent::onReconfigure(); $this->client->resetApplication(); $this->configureClient($this->config); $this->client->startApp(); } /** * Adds the required server params. * Note this is done separately from the request cycle since someone might call * `Url::to` before doing a request, which would instantiate the request component with incorrect server params. */ private function initServerGlobal() { $entryUrl = $this->config['entryUrl']; $entryFile = $this->config['entryScript'] ?: basename($entryUrl); $entryScript = $this->config['entryScript'] ?: parse_url($entryUrl, PHP_URL_PATH); $_SERVER = array_merge($_SERVER, [ 'SCRIPT_FILENAME' => $entryFile, 'SCRIPT_NAME' => $entryScript, 'SERVER_NAME' => parse_url($entryUrl, PHP_URL_HOST), 'SERVER_PORT' => parse_url($entryUrl, PHP_URL_PORT) ?: '80', 'HTTPS' => parse_url($entryUrl, PHP_URL_SCHEME) === 'https' ]); } protected function validateConfig() { parent::validateConfig(); $pathToConfig = codecept_absolute_path($this->config['configFile']); if (!is_file($pathToConfig)) { throw new ModuleConfigException( __CLASS__, "The application config file does not exist: " . $pathToConfig ); } if (!in_array($this->config['responseCleanMethod'], Yii2Connector::CLEAN_METHODS)) { throw new ModuleConfigException( __CLASS__, "The response clean method must be one of: " . implode(", ", Yii2Connector::CLEAN_METHODS) ); } if (!in_array($this->config['requestCleanMethod'], Yii2Connector::CLEAN_METHODS)) { throw new ModuleConfigException( __CLASS__, "The response clean method must be one of: " . implode(", ", Yii2Connector::CLEAN_METHODS) ); } } protected function configureClient(array $settings) { $settings['configFile'] = codecept_absolute_path($settings['configFile']); foreach ($settings as $key => $value) { if (property_exists($this->client, $key)) { $this->client->$key = $value; } } $this->client->resetApplication(); } /** * Instantiates the client based on module configuration */ protected function recreateClient() { $entryUrl = $this->config['entryUrl']; $entryFile = $this->config['entryScript'] ?: basename($entryUrl); $entryScript = $this->config['entryScript'] ?: parse_url($entryUrl, PHP_URL_PATH); $this->client = new Yii2Connector([ 'SCRIPT_FILENAME' => $entryFile, 'SCRIPT_NAME' => $entryScript, 'SERVER_NAME' => parse_url($entryUrl, PHP_URL_HOST), 'SERVER_PORT' => parse_url($entryUrl, PHP_URL_PORT) ?: '80', 'HTTPS' => parse_url($entryUrl, PHP_URL_SCHEME) === 'https' ]); $this->configureClient($this->config); } public function _before(TestInterface $test) { $this->recreateClient(); $this->client->startApp(); $this->connectionWatcher = new Yii2Connector\ConnectionWatcher(); $this->connectionWatcher->start(); // load fixtures before db transaction if ($test instanceof \Codeception\Test\Cest) { $this->loadFixtures($test->getTestClass()); } else { $this->loadFixtures($test); } $this->startTransactions(); } /** * load fixtures before db transaction * * @param mixed $test instance of test class */ private function loadFixtures($test) { $this->debugSection('Fixtures', 'Loading fixtures'); if (empty($this->loadedFixtures) && method_exists($test, $this->_getConfig('fixturesMethod')) ) { $connectionWatcher = new Yii2Connector\ConnectionWatcher(); $connectionWatcher->start(); $this->haveFixtures(call_user_func([$test, $this->_getConfig('fixturesMethod')])); $connectionWatcher->stop(); $connectionWatcher->closeAll(); } $this->debugSection('Fixtures', 'Done'); } public function _after(TestInterface $test) { $_SESSION = []; $_FILES = []; $_GET = []; $_POST = []; $_COOKIE = []; $_REQUEST = []; $this->rollbackTransactions(); if ($this->config['cleanup']) { foreach ($this->loadedFixtures as $fixture) { $fixture->unloadFixtures(); } $this->loadedFixtures = []; } if ($this->client !== null) { $this->client->resetApplication(); } if (isset($this->connectionWatcher)) { $this->connectionWatcher->stop(); $this->connectionWatcher->closeAll(); unset($this->connectionWatcher); } parent::_after($test); } protected function startTransactions() { if ($this->config['transaction']) { $this->transactionForcer = new Yii2Connector\TransactionForcer($this->config['ignoreCollidingDSN']); $this->transactionForcer->start(); } } protected function rollbackTransactions() { if (isset($this->transactionForcer)) { $this->transactionForcer->rollbackAll(); $this->transactionForcer->stop(); unset($this->transactionForcer); } } public function _parts() { return ['orm', 'init', 'fixtures', 'email']; } /** * Authenticates a user on a site without submitting a login form. * Use it for fast pragmatic authorization in functional tests. * * ```php * amLoggedInAs(1); * * // User object is passed as parameter * $admin = \app\models\User::findByUsername('admin'); * $I->amLoggedInAs($admin); * ``` * Requires the `user` component to be enabled and configured. * * @param $user * @throws \Codeception\Exception\ModuleException */ public function amLoggedInAs($user) { try { $this->client->findAndLoginUser($user); } catch (ConfigurationException $e) { throw new ModuleException($this, $e->getMessage()); } catch (\RuntimeException $e) { throw new ModuleException($this, $e->getMessage()); } } /** * Creates and loads fixtures from a config. * The signature is the same as for the `fixtures()` method of `yii\test\FixtureTrait` * * ```php * haveFixtures([ * 'posts' => PostsFixture::className(), * 'user' => [ * 'class' => UserFixture::className(), * 'dataFile' => '@tests/_data/models/user.php', * ], * ]); * ``` * * Note: if you need to load fixtures before a test (probably before the * cleanup transaction is started; `cleanup` option is `true` by default), * you can specify the fixtures in the `_fixtures()` method of a test case * * ```php * [ * 'class' => UserFixture::className(), * 'dataFile' => codecept_data_dir() . 'user.php' * ] * ]; * } * ``` * instead of calling `haveFixtures` in Cest `_before` * * @param $fixtures * @part fixtures */ public function haveFixtures($fixtures) { if (empty($fixtures)) { return; } $fixturesStore = new Yii2Connector\FixturesStore($fixtures); $fixturesStore->unloadFixtures(); $fixturesStore->loadFixtures(); $this->loadedFixtures[] = $fixturesStore; } /** * Returns all loaded fixtures. * Array of fixture instances * * @part fixtures * @return array */ public function grabFixtures() { return call_user_func_array( 'array_merge', array_map( // merge all fixtures from all fixture stores function ($fixturesStore) { return $fixturesStore->getFixtures(); }, $this->loadedFixtures ) ); } /** * Gets a fixture by name. * Returns a Fixture instance. If a fixture is an instance of * `\yii\test\BaseActiveFixture` a second parameter can be used to return a * specific model: * * ```php * haveFixtures(['users' => UserFixture::className()]); * * $users = $I->grabFixture('users'); * * // get first user by key, if a fixture is an instance of ActiveFixture * $user = $I->grabFixture('users', 'user1'); * ``` * * @param $name * @return mixed * @throws \Codeception\Exception\ModuleException if the fixture is not found * @part fixtures */ public function grabFixture($name, $index = null) { $fixtures = $this->grabFixtures(); if (!isset($fixtures[$name])) { throw new ModuleException($this, "Fixture $name is not loaded"); } $fixture = $fixtures[$name]; if ($index === null) { return $fixture; } if ($fixture instanceof \yii\test\BaseActiveFixture) { return $fixture->getModel($index); } throw new ModuleException($this, "Fixture $name is not an instance of ActiveFixture and can't be loaded with second parameter"); } /** * Inserts a record into the database. * * ``` php * haveRecord('app\models\User', array('name' => 'Davert')); * ?> * ``` * * @param $model * @param array $attributes * @return mixed * @part orm */ public function haveRecord($model, $attributes = []) { /** @var $record \yii\db\ActiveRecord * */ $record = \Yii::createObject($model); $record->setAttributes($attributes, false); $res = $record->save(false); if (!$res) { $this->fail("Record $model was not saved: " . \yii\helpers\Json::encode($record->errors)); } return $record->primaryKey; } /** * Checks that a record exists in the database. * * ``` php * $I->seeRecord('app\models\User', array('name' => 'davert')); * ``` * * @param $model * @param array $attributes * @part orm */ public function seeRecord($model, $attributes = []) { $record = $this->findRecord($model, $attributes); if (!$record) { $this->fail("Couldn't find $model with " . json_encode($attributes)); } $this->debugSection($model, json_encode($record)); } /** * Checks that a record does not exist in the database. * * ``` php * $I->dontSeeRecord('app\models\User', array('name' => 'davert')); * ``` * * @param $model * @param array $attributes * @part orm */ public function dontSeeRecord($model, $attributes = []) { $record = $this->findRecord($model, $attributes); $this->debugSection($model, json_encode($record)); if ($record) { $this->fail("Unexpectedly managed to find $model with " . json_encode($attributes)); } } /** * Retrieves a record from the database * * ``` php * $category = $I->grabRecord('app\models\User', array('name' => 'davert')); * ``` * * @param $model * @param array $attributes * @return mixed * @part orm */ public function grabRecord($model, $attributes = []) { return $this->findRecord($model, $attributes); } /** * @param string $model Class name * @param array $attributes * @return mixed */ protected function findRecord($model, $attributes = []) { if (!class_exists($model)) { throw new \RuntimeException("Class $model does not exist"); } $rc = new \ReflectionClass($model); if ($rc->hasMethod('find') && ($findMethod = $rc->getMethod('find')) && $findMethod->isStatic() && $findMethod->isPublic() && $findMethod->getNumberOfRequiredParameters() === 0 ) { $activeQuery = $findMethod->invoke(null); if ($activeQuery instanceof QueryInterface) { return $activeQuery->andWhere($attributes)->one(); } throw new \RuntimeException("$model::find() must return an instance of yii\db\QueryInterface"); } throw new \RuntimeException("Class $model does not have a public static find() method without required parameters"); } /** * Similar to `amOnPage` but accepts a route as first argument and params as second * * ``` * $I->amOnRoute('site/view', ['page' => 'about']); * ``` * * @param string $route A route * @param array $params Additional route parameters */ public function amOnRoute($route, array $params = []) { array_unshift($params, $route); $this->amOnPage($params); } /** * Opens the page for the given relative URI or route. * * ``` php * amOnPage('/'); * // opens /register page * $I->amOnPage('/register'); * // opens customer view page for id 25 * $I->amOnPage(['customer/view', 'id' => 25]); * ``` * * @param string|array $page the URI or route in array format */ public function amOnPage($page) { parent::amOnPage($page); } /** * To support to use the behavior of urlManager component * for the methods like this: amOnPage(), sendAjaxRequest() and etc. * @param $method * @param $uri * @param array $parameters * @param array $files * @param array $server * @param null $content * @param bool $changeHistory * @return mixed */ protected function clientRequest($method, $uri, array $parameters = [], array $files = [], array $server = [], $content = null, $changeHistory = true) { return parent::clientRequest($method, $this->client->createUrl($uri), $parameters, $files, $server, $content, $changeHistory); } /** * Gets a component from the Yii container. Throws an exception if the * component is not available * * ```php * grabComponent('mailer'); * ``` * * @param $component * @return mixed * @throws \Codeception\Exception\ModuleException * @deprecated in your tests you can use \Yii::$app directly. */ public function grabComponent($component) { try { return $this->client->getComponent($component); } catch (ConfigurationException $e) { throw new ModuleException($this, $e->getMessage()); } } /** * Checks that an email is sent. * * ```php * seeEmailIsSent(); * * // check that only 3 emails were sent * $I->seeEmailIsSent(3); * ``` * * @param int $num * @throws \Codeception\Exception\ModuleException * @part email */ public function seeEmailIsSent($num = null) { if ($num === null) { $this->assertNotEmpty($this->grabSentEmails(), 'emails were sent'); return; } $this->assertEquals($num, count($this->grabSentEmails()), 'number of sent emails is equal to ' . $num); } /** * Checks that no email was sent * * @part email */ public function dontSeeEmailIsSent() { $this->seeEmailIsSent(0); } /** * Returns array of all sent email messages. * Each message implements the `yii\mail\MessageInterface` interface. * Useful to perform additional checks using the `Asserts` module: * * ```php * seeEmailIsSent(); * $messages = $I->grabSentEmails(); * $I->assertEquals('admin@site,com', $messages[0]->getTo()); * ``` * * @part email * @return array * @throws \Codeception\Exception\ModuleException */ public function grabSentEmails() { try { return $this->client->getEmails(); } catch (ConfigurationException $e) { throw new ModuleException($this, $e->getMessage()); } } /** * Returns the last sent email: * * ```php * seeEmailIsSent(); * $message = $I->grabLastSentEmail(); * $I->assertEquals('admin@site,com', $message->getTo()); * ``` * @part email */ public function grabLastSentEmail() { $this->seeEmailIsSent(); $messages = $this->grabSentEmails(); return end($messages); } /** * Returns a list of regex patterns for recognized domain names * * @return array */ public function getInternalDomains() { return $this->client->getInternalDomains(); } private function defineConstants() { defined('YII_DEBUG') or define('YII_DEBUG', true); defined('YII_ENV') or define('YII_ENV', 'test'); defined('YII_ENABLE_ERROR_HANDLER') or define('YII_ENABLE_ERROR_HANDLER', false); } /** * Sets a cookie and, if validation is enabled, signs it. * @param string $name The name of the cookie * @param string $val The value of the cookie * @param array $params Additional cookie params like `domain`, `path`, `expires` and `secure`. */ public function setCookie($name, $val, array $params = []) { parent::setCookie($name, $this->client->hashCookieData($name, $val), $params); } /** * Creates the CSRF Cookie. * @param string $val The value of the CSRF token * @return string[] Returns an array containing the name of the CSRF param and the masked CSRF token. */ public function createAndSetCsrfCookie($val) { $masked = $this->client->maskToken($val); $name = $this->client->getCsrfParamName(); $this->setCookie($name, $val); return [$name, $masked]; } public function _afterSuite() { parent::_afterSuite(); codecept_debug('Suite done, restoring $_SERVER to original'); $_SERVER = $this->server; } /** * Initialize an empty session. Implements MultiSession. */ public function _initializeSession() { $this->client->removeContext(); $this->headers = []; $_SESSION = []; $_COOKIE = []; } /** * Return the session content for future restoring. Implements MultiSession. * @return array backup data */ public function _backupSession() { if (isset(Yii::$app) && Yii::$app->session->useCustomStorage) { throw new ModuleException($this, "Yii2 MultiSession only supports the default session backend."); } return [ 'clientContext' => $this->client->getContext(), 'headers' => $this->headers, 'cookie' => isset($_COOKIE) ? $_COOKIE : [], 'session' => isset($_SESSION) ? $_SESSION : [], ]; } /** * Restore a session. Implements MultiSession. * @param array output of _backupSession() */ public function _loadSession($session) { $this->client->setContext($session['clientContext']); $this->headers = $session['headers']; $_SESSION = $session['session']; $_COOKIE = $session['cookie']; // reset Yii::$app->user if (isset(Yii::$app)) { $definitions = Yii::$app->getComponents(true); if (Yii::$app->has('user', true)) { Yii::$app->set('user', $definitions['user']); } } } /** * Close and dump a session. Implements MultiSession. */ public function _closeSession($session = null) { if (!$session) { $this->_initializeSession(); } } }