diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index d2093f1..1203ebb 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -8,7 +8,7 @@ jobs: strategy: matrix: - php: [7.4, 8.0, 8.1] + php: [8.0, 8.1] steps: - name: Checkout code diff --git a/.gitignore b/.gitignore index 241050f..31a345f 100644 --- a/.gitignore +++ b/.gitignore @@ -1,4 +1,5 @@ /.idea/ +/nbproject/ /vendor/ /composer.lock tests/_support diff --git a/composer.json b/composer.json index a539d2c..6cadf21 100644 --- a/composer.json +++ b/composer.json @@ -16,19 +16,20 @@ "name":"Michael Bodnarchuk" } ], - "minimum-stability": "RC", + "minimum-stability": "dev", "require": { - "php": ">=7.4.0 <=8.1 | ~8.1.0", - "codeception/lib-innerbrowser": "^1.0", - "codeception/codeception": "^4.0" + "php": "^8.0", + "codeception/codeception": "^5.0.0-alpha2", + "codeception/lib-innerbrowser": "^3.0" }, "require-dev": { "yiisoft/yii2": "dev-master", "yiisoft/yii2-app-advanced": "dev-master", - "codeception/verify": "<2", + "phpunit/phpunit": "dev-master as 9.5.99", + "codeception/verify": "^2.2", "codemix/yii2-localeurls": "^1.7", - "codeception/module-asserts": "^2.0", - "codeception/module-filesystem": "^2.0" + "codeception/module-asserts": "^3.0", + "codeception/module-filesystem": "^3.0" }, "autoload":{ "classmap": ["src/"] @@ -40,6 +41,9 @@ ] }, "config": { + "allow-plugins": { + "yiisoft/yii2-composer": true + }, "classmap-authoritative": true }, "repositories": [ diff --git a/src/Codeception/Lib/Connector/Yii2.php b/src/Codeception/Lib/Connector/Yii2.php index ff62658..8211220 100644 --- a/src/Codeception/Lib/Connector/Yii2.php +++ b/src/Codeception/Lib/Connector/Yii2.php @@ -116,7 +116,7 @@ public function resetApplication($closeSession = true) } Yii::$app = null; \yii\web\UploadedFile::reset(); - if (method_exists(\yii\base\Event::className(), 'offAll')) { + if (method_exists(\yii\base\Event::class, 'offAll')) { \yii\base\Event::offAll(); } Yii::setLogger(null); diff --git a/src/Codeception/Lib/Connector/Yii2/FixturesStore.php b/src/Codeception/Lib/Connector/Yii2/FixturesStore.php index 53023ae..113c0a3 100644 --- a/src/Codeception/Lib/Connector/Yii2/FixturesStore.php +++ b/src/Codeception/Lib/Connector/Yii2/FixturesStore.php @@ -29,7 +29,7 @@ public function fixtures() public function globalFixtures() { return [ - InitDbFixture::className() + InitDbFixture::class ]; } } diff --git a/src/Codeception/Module/Yii2.php b/src/Codeception/Module/Yii2.php index 792e50b..69d75c7 100644 --- a/src/Codeception/Module/Yii2.php +++ b/src/Codeception/Module/Yii2.php @@ -19,6 +19,7 @@ use yii\db\Connection; use yii\db\QueryInterface; use yii\db\Transaction; +use yii\helpers\Url; /** * This module provides integration with [Yii framework](http://www.yiiframework.com/) (2.0). @@ -131,7 +132,7 @@ * * ```php * haveFixtures(['posts' => PostsFixture::className()]); + * $I->haveFixtures(['posts' => PostsFixture::class]); * ``` * * or, if you need to load fixtures before the test, you @@ -142,7 +143,7 @@ * // inside Cest file or Codeception\TestCase\Unit * public function _fixtures() * { - * return ['posts' => PostsFixture::className()] + * return ['posts' => PostsFixture::class] * } * ``` * @@ -171,7 +172,7 @@ class Yii2 extends Framework implements ActiveRecord, MultiSession, PartedModule * Application config file must be set. * @var array */ - protected $config = [ + protected array $config = [ 'fixturesMethod' => '_fixtures', 'cleanup' => true, 'ignoreCollidingDSN' => false, @@ -186,12 +187,12 @@ class Yii2 extends Framework implements ActiveRecord, MultiSession, PartedModule 'applicationClass' => null, ]; - protected $requiredFields = ['configFile']; + protected array $requiredFields = ['configFile']; /** * @var Yii2Connector\FixturesStore[] */ - public $loadedFixtures = []; + public array $loadedFixtures = []; /** * Helper to manage database connections @@ -256,7 +257,7 @@ private function initServerGlobal() ]); } - protected function validateConfig() + protected function validateConfig(): void { parent::validateConfig(); @@ -402,7 +403,7 @@ protected function rollbackTransactions() } } - public function _parts() + public function _parts(): array { return ['orm', 'init', 'fixtures', 'email']; } @@ -443,9 +444,9 @@ public function amLoggedInAs($user) * ```php * haveFixtures([ - * 'posts' => PostsFixture::className(), + * 'posts' => PostsFixture::class, * 'user' => [ - * 'class' => UserFixture::className(), + * 'class' => UserFixture::class, * 'dataFile' => '@tests/_data/models/user.php', * ], * ]); @@ -461,7 +462,7 @@ public function amLoggedInAs($user) * public function _fixtures(){ * return [ * 'user' => [ - * 'class' => UserFixture::className(), + * 'class' => UserFixture::class, * 'dataFile' => codecept_data_dir() . 'user.php' * ] * ]; @@ -511,7 +512,7 @@ function ($fixturesStore) { * * ```php * haveFixtures(['users' => UserFixture::className()]); + * $I->haveFixtures(['users' => UserFixture::class]); * * $users = $I->grabFixture('users'); * @@ -577,7 +578,7 @@ public function haveRecord($model, $attributes = []) * @param array $attributes * @part orm */ - public function seeRecord($model, $attributes = []) + public function seeRecord(string $model, array $attributes = []): void { $record = $this->findRecord($model, $attributes); if (!$record) { @@ -597,7 +598,7 @@ public function seeRecord($model, $attributes = []) * @param array $attributes * @part orm */ - public function dontSeeRecord($model, $attributes = []) + public function dontSeeRecord(string $model, array $attributes = []): void { $record = $this->findRecord($model, $attributes); $this->debugSection($model, json_encode($record)); @@ -618,7 +619,7 @@ public function dontSeeRecord($model, $attributes = []) * @return mixed * @part orm */ - public function grabRecord($model, $attributes = []) + public function grabRecord(string $model, array $attributes = []): mixed { return $this->findRecord($model, $attributes); } @@ -628,7 +629,7 @@ public function grabRecord($model, $attributes = []) * @param array $attributes * @return mixed */ - protected function findRecord($model, $attributes = []) + protected function findRecord(string $model, array $attributes = []): mixed { if (!class_exists($model)) { throw new \RuntimeException("Class $model does not exist"); @@ -660,10 +661,14 @@ protected function findRecord($model, $attributes = []) * @param string $route A route * @param array $params Additional route parameters */ - public function amOnRoute($route, array $params = []) + public function amOnRoute(string $route, array $params = []): void { + if (Yii::$app->controller === null) { + $route = "/{$route}"; + } + array_unshift($params, $route); - $this->amOnPage($params); + $this->amOnPage(Url::to($params)); } /** @@ -679,7 +684,7 @@ public function amOnRoute($route, array $params = []) * * @param string|array $page the URI or route in array format */ - public function amOnPage($page) + public function amOnPage(string $page): void { parent::amOnPage($page); } @@ -715,7 +720,7 @@ protected function clientRequest(string $method, string $uri, array $parameters * @throws \Codeception\Exception\ModuleException * @deprecated in your tests you can use \Yii::$app directly. */ - public function grabComponent($component) + public function grabComponent(mixed $component) { try { return $this->client->getComponent($component); @@ -740,7 +745,7 @@ public function grabComponent($component) * @throws \Codeception\Exception\ModuleException * @part email */ - public function seeEmailIsSent($num = null) + public function seeEmailIsSent(int $num = null): void { if ($num === null) { $this->assertNotEmpty($this->grabSentEmails(), 'emails were sent'); @@ -754,7 +759,7 @@ public function seeEmailIsSent($num = null) * * @part email */ - public function dontSeeEmailIsSent() + public function dontSeeEmailIsSent(): void { $this->seeEmailIsSent(0); } @@ -775,7 +780,7 @@ public function dontSeeEmailIsSent() * @return array * @throws \Codeception\Exception\ModuleException */ - public function grabSentEmails() + public function grabSentEmails(): array { try { return $this->client->getEmails(); @@ -795,7 +800,7 @@ public function grabSentEmails() * ``` * @part email */ - public function grabLastSentEmail() + public function grabLastSentEmail(): object { $this->seeEmailIsSent(); $messages = $this->grabSentEmails(); @@ -814,7 +819,7 @@ public function getInternalDomains(): array return $this->client->getInternalDomains(); } - private function defineConstants() + private function defineConstants(): void { defined('YII_DEBUG') or define('YII_DEBUG', true); defined('YII_ENV') or define('YII_ENV', 'test'); @@ -837,7 +842,7 @@ public function setCookie($name, $val, $params = []) * @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) + public function createAndSetCsrfCookie(string $val): array { $masked = $this->client->maskToken($val); $name = $this->client->getCsrfParamName(); @@ -845,7 +850,7 @@ public function createAndSetCsrfCookie($val) return [$name, $masked]; } - public function _afterSuite() + public function _afterSuite(): void { parent::_afterSuite(); codecept_debug('Suite done, restoring $_SERVER to original'); @@ -856,7 +861,7 @@ public function _afterSuite() /** * Initialize an empty session. Implements MultiSession. */ - public function _initializeSession() + public function _initializeSession(): void { $this->client->removeContext(); $this->headers = []; @@ -868,7 +873,7 @@ public function _initializeSession() * Return the session content for future restoring. Implements MultiSession. * @return array backup data */ - public function _backupSession() + public function _backupSession(): array { if (isset(Yii::$app) && Yii::$app->session->useCustomStorage) { throw new ModuleException($this, "Yii2 MultiSession only supports the default session backend."); @@ -885,7 +890,7 @@ public function _backupSession() * Restore a session. Implements MultiSession. * @param array output of _backupSession() */ - public function _loadSession($session) + public function _loadSession($session): void { $this->client->setContext($session['clientContext']); $this->headers = $session['headers']; @@ -904,7 +909,7 @@ public function _loadSession($session) /** * Close and dump a session. Implements MultiSession. */ - public function _closeSession($session = null) + public function _closeSession($session = null): void { if (!$session) { $this->_initializeSession(); diff --git a/tests/bootstrap.php b/tests/bootstrap.php index 71170fb..f10531f 100644 --- a/tests/bootstrap.php +++ b/tests/bootstrap.php @@ -2,9 +2,11 @@ defined('YII_DEBUG') || define('YII_DEBUG', true); defined('YII_ENV') || define('YII_ENV', 'test'); +require dirname(__DIR__) . '/vendor/autoload.php'; + Yii::$container = new \yii\di\Container(); -$link = __DIR__ . '/../vendor/yiisoft/yii2-app-advanced/vendor'; -if (!file_exists($link) && !symlink(__DIR__ . '/../vendor', $link)) { +$link = dirname(__DIR__) . '/vendor/yiisoft/yii2-app-advanced/vendor'; +if (!file_exists($link) && !symlink(dirname(__DIR__) . '/vendor', $link)) { die('failed to create symlink'); -} +} \ No newline at end of file diff --git a/tests/cases/closeConnections/codeception.yml b/tests/cases/closeConnections/codeception.yml index fe8df06..8045bf4 100644 --- a/tests/cases/closeConnections/codeception.yml +++ b/tests/cases/closeConnections/codeception.yml @@ -1,6 +1,6 @@ paths: tests: . - log: ../../_output + output: ../../_output data: _data support: ../../_support namespace: tests\ diff --git a/tests/cases/closeConnectionsNoCleanup/codeception.yml b/tests/cases/closeConnectionsNoCleanup/codeception.yml index 1bfb23c..fd2eb9a 100644 --- a/tests/cases/closeConnectionsNoCleanup/codeception.yml +++ b/tests/cases/closeConnectionsNoCleanup/codeception.yml @@ -1,6 +1,6 @@ paths: tests: . - log: ../../_output + output: ../../_output data: _data support: ../../_support namespace: tests\ diff --git a/tests/cases/events/codeception.yml b/tests/cases/events/codeception.yml index caf01d1..6c75eef 100644 --- a/tests/cases/events/codeception.yml +++ b/tests/cases/events/codeception.yml @@ -1,6 +1,6 @@ paths: tests: . - log: ../../_output + output: ../../_output data: _data support: ../../_support namespace: tests\ diff --git a/tests/cases/events/functional/ResponseCest.php b/tests/cases/events/functional/ResponseCest.php index 4d7a2d3..30e7f37 100644 --- a/tests/cases/events/functional/ResponseCest.php +++ b/tests/cases/events/functional/ResponseCest.php @@ -17,11 +17,11 @@ public function testAfterSend(FunctionalTester $I) $sources[] = 'bootstrap'; }); $I->assertEmpty($sources); - $I->amOnPage('/'); + $I->amOnRoute('/'); $I->assertEquals(['config', 'bootstrap'], $sources); $sources = []; - $I->amOnPage('/'); + $I->amOnRoute('/'); $I->assertEquals(['config', 'bootstrap'], $sources); } @@ -40,11 +40,11 @@ public function testAfterSendWithRecreate(FunctionalTester $I, \Codeception\Modu $sources[] = 'bootstrap'; }); $I->assertEmpty($sources); - $I->amOnPage('/'); + $I->amOnRoute('/'); $I->assertEquals(['config', 'bootstrap'], $sources); $sources = []; - $I->amOnPage('/'); + $I->amOnRoute('/'); // The module should fall back to the CLEAN_CLEAR method and keep event handlers intact. $I->assertEquals(['config', 'bootstrap'], $sources); @@ -66,14 +66,14 @@ public function testAfterSendWithForcedRecreate(FunctionalTester $I, \Codeceptio }); $I->assertEmpty($sources); - $I->amOnPage('/'); + $I->amOnRoute('/'); // We recreated the response component, since it has an event handler in its config // that event handler will still work. $I->assertEquals(['config'], $sources); $sources = []; - $I->amOnPage('/'); + $I->amOnRoute('/'); // We recreated the response component, since it has an event handler in its config // that event handler will still work. diff --git a/tests/cases/locale-urls/codeception.yml b/tests/cases/locale-urls/codeception.yml index caf01d1..6c75eef 100644 --- a/tests/cases/locale-urls/codeception.yml +++ b/tests/cases/locale-urls/codeception.yml @@ -1,6 +1,6 @@ paths: tests: . - log: ../../_output + output: ../../_output data: _data support: ../../_support namespace: tests\ diff --git a/tests/cases/locale-urls/functional/LocaleUrlCest.php b/tests/cases/locale-urls/functional/LocaleUrlCest.php index f146389..c9e7638 100644 --- a/tests/cases/locale-urls/functional/LocaleUrlCest.php +++ b/tests/cases/locale-urls/functional/LocaleUrlCest.php @@ -13,12 +13,12 @@ public function testInstantiation(FunctionalTester $I) public function testMultipleGet(FunctionalTester $I) { - $I->amOnPage('/en/site/form'); - $I->amOnPage('/en/site/form'); + $I->amOnRoute('/en/site/form'); + $I->amOnRoute('/en/site/form'); } public function testFormSubmit(FunctionalTester $I) { - $I->amOnPage('site/form'); + $I->amOnRoute('site/form'); $I->seeResponseCodeIs(200); $I->fillField('#test', 'test'); @@ -28,7 +28,7 @@ public function testFormSubmit(FunctionalTester $I) public function testFormSubmit2(FunctionalTester $I) { - $I->amOnPage('/en/site/form'); + $I->amOnRoute('/en/site/form'); $I->seeResponseCodeIs(200); $I->submitForm('form', [ 'login-form[login]' => 'user', diff --git a/tests/cases/mock-mailer/codeception.yml b/tests/cases/mock-mailer/codeception.yml index b0d1647..dcd92b1 100644 --- a/tests/cases/mock-mailer/codeception.yml +++ b/tests/cases/mock-mailer/codeception.yml @@ -1,6 +1,6 @@ paths: tests: . - log: ../../_output + output: ../../_output data: _data support: ../../_support namespace: tests\ diff --git a/tests/cases/mock-mailer/functional/MockMailerCest.php b/tests/cases/mock-mailer/functional/MockMailerCest.php index 9699896..fb61035 100644 --- a/tests/cases/mock-mailer/functional/MockMailerCest.php +++ b/tests/cases/mock-mailer/functional/MockMailerCest.php @@ -12,14 +12,14 @@ public function testInstantiation(FunctionalTester $I) public function testCountMailSentWithoutRedirect(FunctionalTester $I) { - $I->amOnPage('site/send-mail-without-redirect'); + $I->amOnRoute('site/send-mail-without-redirect'); $I->seeEmailIsSent(1); } public function testCountMailSentWithRedirect(FunctionalTester $I) { - $I->amOnPage('site/send-mail-with-redirect'); + $I->amOnRoute('site/send-mail-with-redirect'); $I->seeEmailIsSent(1); } diff --git a/tests/cases/pageCacheHeaderAlreadySent/codeception.yml b/tests/cases/pageCacheHeaderAlreadySent/codeception.yml index 01393b5..e17b226 100644 --- a/tests/cases/pageCacheHeaderAlreadySent/codeception.yml +++ b/tests/cases/pageCacheHeaderAlreadySent/codeception.yml @@ -1,6 +1,6 @@ paths: tests: . - log: ../../_output + output: ../../_output data: _data support: ../../_support namespace: tests\ diff --git a/tests/cases/pageCacheHeaderAlreadySent/functional/PageCest.php b/tests/cases/pageCacheHeaderAlreadySent/functional/PageCest.php index 3bec510..c2fa371 100644 --- a/tests/cases/pageCacheHeaderAlreadySent/functional/PageCest.php +++ b/tests/cases/pageCacheHeaderAlreadySent/functional/PageCest.php @@ -4,10 +4,10 @@ class PageCest { public function testCache(\tests\FunctionalTester $I) { - $I->amOnPage('user/index'); + $I->amOnRoute('user/index'); $I->canSeeResponseCodeIs(200); - $I->amOnPage('user/index'); + $I->amOnRoute('user/index'); $I->canSeeResponseCodeIs(200); } } \ No newline at end of file diff --git a/tests/cases/simple/codeception.yml b/tests/cases/simple/codeception.yml index cb08201..bfca355 100644 --- a/tests/cases/simple/codeception.yml +++ b/tests/cases/simple/codeception.yml @@ -1,6 +1,6 @@ paths: tests: . - log: ../../_output + output: ../../_output data: _data support: ../../_support namespace: tests\ diff --git a/tests/cases/simple/functional.suite.yml b/tests/cases/simple/functional.suite.yml index 6da4e38..8634679 100644 --- a/tests/cases/simple/functional.suite.yml +++ b/tests/cases/simple/functional.suite.yml @@ -1,9 +1,3 @@ -# Codeception Test Suite Configuration -# -# Suite for functional tests -# Emulate web requests and make application process them -# Include one of framework modules (Symfony2, Yii2, Laravel5) to use it -# Remove this suite if you don't use frameworks actor: FunctionalTester modules: enabled: diff --git a/tests/cases/simple/functional/SimpleCest.php b/tests/cases/simple/functional/SimpleCest.php index 00db22d..f328c9e 100644 --- a/tests/cases/simple/functional/SimpleCest.php +++ b/tests/cases/simple/functional/SimpleCest.php @@ -15,9 +15,8 @@ public function testInstantiation(FunctionalTester $I) public function testFormSubmit(FunctionalTester $I) { - $I->amOnPage('site/form'); + $I->amOnRoute('/site/form'); $I->seeResponseCodeIs(200); - $I->fillField('#test', 'test'); $I->click('#submit'); $I->canSeeResponseCodeIs(201); @@ -25,7 +24,7 @@ public function testFormSubmit(FunctionalTester $I) public function testFormSubmit2(FunctionalTester $I) { - $I->amOnPage('site/form'); + $I->amOnRoute('/site/form'); $I->seeResponseCodeIs(200); $I->submitForm('form', [ 'login-form[login]' => 'user', @@ -36,8 +35,8 @@ public function testFormSubmit2(FunctionalTester $I) public function testException(FunctionalTester $I) { - $I->expectException(new \Exception('This is not an HttpException'), function() use ($I) { - $I->amOnPage('site/exception'); + $I->expectThrowable(new \Exception('This is not an HttpException'), function() use ($I) { + $I->amOnRoute('/site/exception'); }); $I->assertInstanceOf(Application::class, \Yii::$app); } @@ -46,29 +45,29 @@ public function testExceptionInBeforeRequest(FunctionalTester $I) { $e = new \Exception('This is not an HttpException'); \Yii::$app->params['throw'] = $e; - $I->expectException($e, function() use ($I) { - $I->amOnPage('site/exception'); + $I->expectThrowable($e, function() use ($I) { + $I->amOnRoute('/site/exception'); }); } public function testExitException(FunctionalTester $I) { - $I->amOnPage('site/end'); + $I->amOnRoute('/site/end'); $I->seeResponseCodeIs(500); } public function testEmptyResponse(FunctionalTester $I) { - $I->amOnPage('site/empty-response'); + $I->amOnRoute('/site/empty-response'); $I->seeResponseCodeIs(200); } public function testMissingUser(FunctionalTester $I) { - $I->expectException(ModuleException::class, function() use ($I) { + $I->expectThrowable(ModuleException::class, function() use ($I) { $I->amLoggedInAs('nobody'); }); - $I->amOnPage('site/index'); + $I->amOnRoute('/site/index'); $I->assertTrue(\Yii::$app->user->isGuest); } } \ No newline at end of file diff --git a/tests/cases/sqlite/codeception.yml b/tests/cases/sqlite/codeception.yml index caf01d1..6c75eef 100644 --- a/tests/cases/sqlite/codeception.yml +++ b/tests/cases/sqlite/codeception.yml @@ -1,6 +1,6 @@ paths: tests: . - log: ../../_output + output: ../../_output data: _data support: ../../_support namespace: tests\ diff --git a/tests/cases/yii2-app-advanced/codeception.yml b/tests/cases/yii2-app-advanced/codeception.yml index 744faf9..35d94f1 100644 --- a/tests/cases/yii2-app-advanced/codeception.yml +++ b/tests/cases/yii2-app-advanced/codeception.yml @@ -2,7 +2,7 @@ namespace: frontend\tests actor_suffix: Tester paths: tests: ../../../vendor/yiisoft/yii2-app-advanced/frontend/tests - log: ../../_output + output: ../../_output data: ../../../vendor/yiisoft/yii2-app-advanced/frontend/tests/_data support: ../../../vendor/yiisoft/yii2-app-advanced/frontend/tests/_support bootstrap: _bootstrap.php