diff --git a/.git-blame-ignore-revs b/.git-blame-ignore-revs
new file mode 100644
index 000000000..011c056bb
--- /dev/null
+++ b/.git-blame-ignore-revs
@@ -0,0 +1,8 @@
+# Reformat code te be PSR-2 compatible
+93cc82c4bf42cea403e1acaab201338bea304b6e
+# Convert to short syntax (array)
+332030325fbad38a64c5e60980d3b14b6434d6dd
+# Convert to short syntax
+b0fcdfab1aecaeb620f75a83f15aa02bc25765a0
+# Fix codestyle
+0f91f32ecff52ef479addb0a5013342d59fe0697
diff --git a/.gitattributes b/.gitattributes
index 3e9092c68..705fb391d 100644
--- a/.gitattributes
+++ b/.gitattributes
@@ -1,6 +1,7 @@
# Ignore all test and documentation for archive
-/.github export-ignore
-/.gitattributes export-ignore
-/.scrutinizer.yml export-ignore
-/.travis.yml export-ignore
-/docs export-ignore
+/.github export-ignore
+/.git-blame-ignore-revs export-ignore
+/.gitattributes export-ignore
+/.scrutinizer.yml export-ignore
+/.travis.yml export-ignore
+/docs export-ignore
diff --git a/.github/CONTRIBUTING.md b/.github/CONTRIBUTING.md
index 3d8d32c25..ea75bda5f 100644
--- a/.github/CONTRIBUTING.md
+++ b/.github/CONTRIBUTING.md
@@ -3,5 +3,5 @@ Contributing to Yii2
- [Report an issue](https://github.com/yiisoft/yii2/blob/master/docs/internals/report-an-issue.md)
- [Translate documentation or messages](https://github.com/yiisoft/yii2/blob/master/docs/internals/translation-workflow.md)
-- [Give us feedback or start a design discussion](http://www.yiiframework.com/forum/index.php/forum/42-general-discussions-for-yii-20/)
+- [Give us feedback or start a design discussion](https://www.yiiframework.com/forum/index.php/forum/42-general-discussions-for-yii-20/)
- [Contribute to the core code or fix bugs](https://github.com/yiisoft/yii2/blob/master/docs/internals/git-workflow.md)
diff --git a/.github/ISSUE_TEMPLATE.md b/.github/ISSUE_TEMPLATE.md
index 52ec8692f..a2ee92439 100644
--- a/.github/ISSUE_TEMPLATE.md
+++ b/.github/ISSUE_TEMPLATE.md
@@ -9,6 +9,6 @@
| Q | A
| ---------------- | ---
-| Yii vesion |
+| Yii version |
| PHP version |
| Operating system |
diff --git a/.github/SECURITY.md b/.github/SECURITY.md
index f71384759..405acca4e 100644
--- a/.github/SECURITY.md
+++ b/.github/SECURITY.md
@@ -3,4 +3,4 @@
Please use the [security issue form](https://www.yiiframework.com/security) to report to us any security issue you find in Yii.
DO NOT use the issue tracker or discuss it in the public forum as it will cause more damage than help.
-Please note that as a non-commerial OpenSource project we are not able to pay bounties at the moment.
+Please note that as a non-commercial OpenSource project we are not able to pay bounties at the moment.
diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml
index c2b6bd92e..a5beac653 100644
--- a/.github/workflows/build.yml
+++ b/.github/workflows/build.yml
@@ -10,7 +10,7 @@ jobs:
env:
extensions: dom, json, gd, imagick
- key: cache-v1
+ key: cache-v4
runs-on: ${{ matrix.os }}
@@ -21,16 +21,16 @@ jobs:
- windows-latest
php:
- - "5.6"
- - "7.0"
- - "7.1"
- - "7.2"
- - "7.3"
- "7.4"
+ - "8.0"
+ - "8.1"
+ - "8.2"
+ - "8.3"
+ - "8.4"
steps:
- name: Checkout
- uses: actions/checkout@v2
+ uses: actions/checkout@v5
- name: Setup cache environment
id: cache-env
@@ -41,7 +41,7 @@ jobs:
key: ${{ env.key }}
- name: Cache extensions
- uses: actions/cache@v1
+ uses: actions/cache@v4
with:
path: ${{ steps.cache-env.outputs.dir }}
key: ${{ steps.cache-env.outputs.key }}
@@ -56,21 +56,23 @@ jobs:
- name: Determine composer cache directory on Linux
if: matrix.os == 'ubuntu-latest'
- run: echo "::set-env name=COMPOSER_CACHE_DIR::$(composer config cache-dir)"
+ run: |
+ echo "COMPOSER_CACHE_DIR=$(composer config cache-dir)" >> $GITHUB_ENV
- name: Determine composer cache directory on Windows
if: matrix.os == 'windows-latest'
- run: ECHO "::set-env name=COMPOSER_CACHE_DIR::~\AppData\Local\Composer"
+ run: |
+ echo "COMPOSER_CACHE_DIR=~\AppData\Local\Composer" >> $GITHUB_ENV
- name: Cache dependencies installed with composer
- uses: actions/cache@v1
+ uses: actions/cache@v4
with:
- path: ${{ env.COMPOSER_CACHE_DIR }}
+ path: ${{ steps.cache-env.outputs.dir }}
key: php${{ matrix.php }}-composer-${{ matrix.dependencies }}-${{ hashFiles('**/composer.json') }}
restore-keys: |
php${{ matrix.php }}-composer-${{ matrix.dependencies }}-
- - name: Install dependencies with composer php PHP [5.6 - 7.4]
+ - name: Install dependencies with composer php PHP [5.6 - 8.0]
run: composer update --prefer-dist --no-interaction --no-progress --optimize-autoloader --ansi
- name: Run tests with codeception
@@ -78,4 +80,4 @@ jobs:
sed -i "s/'cookieValidationKey' => ''/'cookieValidationKey' => 'testkey'/" config/web.php
php -S 127.0.0.1:8080 -t public > ./runtime/yii.log 2>&1 &
vendor/bin/codecept run
- shell: bash
\ No newline at end of file
+ shell: bash
diff --git a/.gitignore b/.gitignore
index 5bd9be80b..05fb29d1b 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,6 +1,9 @@
# phpstorm project files
.idea
+# visual studio code project files
+.vscode
+
# netbeans project files
nbproject
diff --git a/README.md b/README.md
index 6db290bfa..981a7f9d9 100644
--- a/README.md
+++ b/README.md
@@ -6,7 +6,7 @@
-Yii 2 Basic Project Template is a skeleton [Yii 2](http://www.yiiframework.com/) application best for
+Yii 2 Basic Project Template is a skeleton [Yii 2](https://www.yiiframework.com/) application best for
rapidly creating small projects.
The template contains the basic features including user login/logout and a contact page.
@@ -37,7 +37,7 @@ DIRECTORY STRUCTURE
REQUIREMENTS
------------
-The minimum requirement by this project template that your Web server supports PHP 5.6.0.
+The minimum requirement by this project template that your Web server supports PHP 7.4.
INSTALLATION
@@ -45,8 +45,8 @@ INSTALLATION
### Install via Composer
-If you do not have [Composer](http://getcomposer.org/), you may install it by following the instructions
-at [getcomposer.org](http://getcomposer.org/doc/00-intro.md#installation-nix).
+If you do not have [Composer](https://getcomposer.org/), you may install it by following the instructions
+at [getcomposer.org](https://getcomposer.org/doc/00-intro.md#installation-nix).
You can then install this project template using the following command:
@@ -63,7 +63,7 @@ http://localhost/basic/web/
### Install from an Archive File
-Extract the archive file downloaded from [yiiframework.com](http://www.yiiframework.com/download/) to
+Extract the archive file downloaded from [yiiframework.com](https://www.yiiframework.com/download/) to
a directory named `basic` that is directly under the Web root.
Set cookie validation key in `config/web.php` file to some random secret string:
@@ -131,8 +131,8 @@ return [
TESTING
-------
-Tests are located in `tests` directory. They are developed with [Codeception PHP Testing Framework](http://codeception.com/).
-By default there are 3 test suites:
+Tests are located in `tests` directory. They are developed with [Codeception PHP Testing Framework](https://codeception.com/).
+By default, there are 3 test suites:
- `unit`
- `functional`
@@ -155,7 +155,7 @@ To execute acceptance tests do the following:
1. Rename `tests/acceptance.suite.yml.example` to `tests/acceptance.suite.yml` to enable suite configuration
-2. Replace `codeception/base` package in `composer.json` with `codeception/codeception` to install full featured
+2. Replace `codeception/base` package in `composer.json` with `codeception/codeception` to install full-featured
version of Codeception
3. Update dependencies with Composer
@@ -164,7 +164,7 @@ To execute acceptance tests do the following:
composer update
```
-4. Download [Selenium Server](http://www.seleniumhq.org/download/) and launch it:
+4. Download [Selenium Server](https://www.seleniumhq.org/download/) and launch it:
```
java -jar ~/selenium-server-standalone-x.xx.x.jar
diff --git a/assets/AppAsset.php b/assets/AppAsset.php
index 47932b165..d9d4cc430 100644
--- a/assets/AppAsset.php
+++ b/assets/AppAsset.php
@@ -1,8 +1,9 @@
=5.6.0",
- "yiisoft/yii2": "~2.0.14",
- "yiisoft/yii2-bootstrap": "~2.0.0",
- "yiisoft/yii2-swiftmailer": "~2.0.0 || ~2.1.0"
+ "php": ">=7.4.0",
+ "yiisoft/yii2": "~2.0.45",
+ "yiisoft/yii2-bootstrap5": "~2.0.2",
+ "yiisoft/yii2-symfonymailer": "~2.0.3"
},
"require-dev": {
"yiisoft/yii2-debug": "~2.1.0",
- "yiisoft/yii2-gii": "~2.1.0",
+ "yiisoft/yii2-gii": "~2.2.0",
"yiisoft/yii2-faker": "~2.0.0",
- "codeception/codeception": "^4.0",
- "codeception/verify": "~0.5.0 || ~1.1.0",
- "codeception/specify": "~0.4.6",
- "symfony/browser-kit": ">=2.7 <=4.2.4",
- "codeception/module-filesystem": "^1.0.0",
- "codeception/module-yii2": "^1.0.0",
- "codeception/module-asserts": "^1.0.0"
+ "codeception/codeception": "^5.0.0 || ^4.0",
+ "codeception/lib-innerbrowser": "^4.0 || ^3.0 || ^1.1",
+ "codeception/module-asserts": "^3.0 || ^1.1",
+ "codeception/module-yii2": "^1.1",
+ "codeception/module-filesystem": "^3.0 || ^2.0 || ^1.1",
+ "codeception/verify": "^3.0 || ^2.2"
},
"config": {
+ "allow-plugins": {
+ "yiisoft/yii2-composer" : true
+ },
"process-timeout": 1800,
"fxp-asset": {
"enabled": false
diff --git a/config/__autocomplete.php b/config/__autocomplete.php
new file mode 100644
index 000000000..e5e1c00d7
--- /dev/null
+++ b/config/__autocomplete.php
@@ -0,0 +1,35 @@
+ 'yii\gii\Module',
];
+ // configuration adjustments for 'dev' environment
+ // requires version `2.1.21` of yii2-debug module
+ $config['bootstrap'][] = 'debug';
+ $config['modules']['debug'] = [
+ 'class' => 'yii\debug\Module',
+ // uncomment the following to add your IP if you are not connecting from localhost.
+ //'allowedIPs' => ['127.0.0.1', '::1'],
+ ];
}
return $config;
diff --git a/config/test.php b/config/test.php
index f95bc031e..fb5e2929e 100644
--- a/config/test.php
+++ b/config/test.php
@@ -1,4 +1,5 @@
[
'db' => $db,
'mailer' => [
+ 'class' => \yii\symfonymailer\Mailer::class,
+ 'viewPath' => '@app/mail',
+ // send all mails to a file by default.
'useFileTransport' => true,
+ 'messageClass' => 'yii\symfonymailer\Message'
],
'assetManager' => [
'basePath' => __DIR__ . '/../web/assets',
diff --git a/config/test_db.php b/config/test_db.php
index f4290e0b0..f10835fe1 100644
--- a/config/test_db.php
+++ b/config/test_db.php
@@ -1,4 +1,5 @@
'site/error',
],
'mailer' => [
- 'class' => 'yii\swiftmailer\Mailer',
- // send all mails to a file by default. You have to set
- // 'useFileTransport' to false and configure a transport
- // for the mailer to send real emails.
+ 'class' => \yii\symfonymailer\Mailer::class,
+ 'viewPath' => '@app/mail',
+ // send all mails to a file by default.
'useFileTransport' => true,
],
'log' => [
diff --git a/controllers/SiteController.php b/controllers/SiteController.php
index 6e8a85d10..67c3f50f8 100644
--- a/controllers/SiteController.php
+++ b/controllers/SiteController.php
@@ -19,7 +19,7 @@ public function behaviors()
{
return [
'access' => [
- 'class' => AccessControl::className(),
+ 'class' => AccessControl::class,
'only' => ['logout'],
'rules' => [
[
@@ -30,7 +30,7 @@ public function behaviors()
],
],
'verbs' => [
- 'class' => VerbFilter::className(),
+ 'class' => VerbFilter::class,
'actions' => [
'logout' => ['post'],
],
diff --git a/mail/layouts/html.php b/mail/layouts/html.php
index bddbc6129..95732cdfa 100644
--- a/mail/layouts/html.php
+++ b/mail/layouts/html.php
@@ -1,9 +1,9 @@
beginPage() ?>
diff --git a/mail/layouts/text.php b/mail/layouts/text.php
new file mode 100644
index 000000000..0873d7728
--- /dev/null
+++ b/mail/layouts/text.php
@@ -0,0 +1,13 @@
+beginPage();
+$this->beginBody();
+echo $content;
+$this->endBody();
+$this->endPage();
diff --git a/models/LoginForm.php b/models/LoginForm.php
index 66d658068..5304eecf4 100644
--- a/models/LoginForm.php
+++ b/models/LoginForm.php
@@ -8,7 +8,7 @@
/**
* LoginForm is the model behind the login form.
*
- * @property-read User|null $user This property is read-only.
+ * @property-read User|null $user
*
*/
class LoginForm extends Model
@@ -60,7 +60,7 @@ public function validatePassword($attribute, $params)
public function login()
{
if ($this->validate()) {
- return Yii::$app->user->login($this->getUser(), $this->rememberMe ? 3600*24*30 : 0);
+ return Yii::$app->user->login($this->getUser(), $this->rememberMe ? 3600 * 24 * 30 : 0);
}
return false;
}
diff --git a/requirements.php b/requirements.php
index 6cf322eb0..db69a36ee 100644
--- a/requirements.php
+++ b/requirements.php
@@ -1,4 +1,5 @@
'Memcache extension',
'mandatory' => false,
'condition' => extension_loaded('memcache') || extension_loaded('memcached'),
- 'by' => 'MemCache',
- 'memo' => extension_loaded('memcached') ? 'To use memcached set MemCache::useMemcached to true.' : ''
+ 'by' => 'MemCache',
+ 'memo' => extension_loaded('memcached') ? 'To use memcached set MemCache::useMemcached to true.' : ''
),
// CAPTCHA:
array(
'name' => 'GD PHP extension with FreeType support',
'mandatory' => false,
'condition' => $gdOK,
- 'by' => 'Captcha',
+ 'by' => 'Captcha',
'memo' => $gdMemo,
),
array(
'name' => 'ImageMagick PHP extension with PNG support',
'mandatory' => false,
'condition' => $imagickOK,
- 'by' => 'Captcha',
+ 'by' => 'Captcha',
'memo' => $imagickMemo,
),
// PHP ini :
@@ -153,7 +154,7 @@
'name' => 'APC extension',
'mandatory' => false,
'condition' => extension_loaded('apc'),
- 'by' => 'ApcCache',
+ 'by' => 'ApcCache',
);
}
diff --git a/tests/_bootstrap.php b/tests/_bootstrap.php
index 131da42af..4b8424f73 100644
--- a/tests/_bootstrap.php
+++ b/tests/_bootstrap.php
@@ -1,6 +1,7 @@
amOnPage(Url::toRoute('/site/contact'));
}
-
+
public function contactPageWorks(AcceptanceTester $I)
{
$I->wantTo('ensure that contact page works');
@@ -25,7 +25,7 @@ public function contactFormCanBeSubmitted(AcceptanceTester $I)
$I->fillField('#contactform-verifycode', 'testme');
$I->click('contact-button');
-
+
$I->wait(2); // wait for button to be clicked
$I->dontSeeElement('#contact-form');
diff --git a/tests/acceptance/HomeCest.php b/tests/acceptance/HomeCest.php
index e65df16ae..98fb6b9f7 100644
--- a/tests/acceptance/HomeCest.php
+++ b/tests/acceptance/HomeCest.php
@@ -6,13 +6,13 @@ class HomeCest
{
public function ensureThatHomePageWorks(AcceptanceTester $I)
{
- $I->amOnPage(Url::toRoute('/site/index'));
+ $I->amOnPage(Url::toRoute('/site/index'));
$I->see('My Company');
-
+
$I->seeLink('About');
$I->click('About');
$I->wait(2); // wait for page to be opened
-
+
$I->see('This is the About page.');
}
}
diff --git a/tests/bin/yii b/tests/bin/yii
index 4923537fb..39df4013d 100755
--- a/tests/bin/yii
+++ b/tests/bin/yii
@@ -3,9 +3,9 @@
/**
* Yii console bootstrap file.
*
- * @link http://www.yiiframework.com/
+ * @link https://www.yiiframework.com/
* @copyright Copyright (c) 2008 Yii Software LLC
- * @license http://www.yiiframework.com/license/
+ * @license https://www.yiiframework.com/license/
*/
defined('YII_DEBUG') or define('YII_DEBUG', true);
diff --git a/tests/bin/yii.bat b/tests/bin/yii.bat
index d516b3a19..ce14c92bc 100644
--- a/tests/bin/yii.bat
+++ b/tests/bin/yii.bat
@@ -4,9 +4,9 @@ rem -------------------------------------------------------------
rem Yii command line bootstrap script for Windows.
rem
rem @author Qiang Xue
-rem @link http://www.yiiframework.com/
+rem @link https://www.yiiframework.com/
rem @copyright Copyright (c) 2008 Yii Software LLC
-rem @license http://www.yiiframework.com/license/
+rem @license https://www.yiiframework.com/license/
rem -------------------------------------------------------------
@setlocal
diff --git a/tests/functional.suite.yml b/tests/functional.suite.yml
index 374c6df45..9d8cf149c 100644
--- a/tests/functional.suite.yml
+++ b/tests/functional.suite.yml
@@ -6,8 +6,9 @@
# RUN `build` COMMAND AFTER ADDING/REMOVING MODULES.
#basic/web/index.php
-class_name: FunctionalTester
+actor: FunctionalTester
modules:
enabled:
- Filesystem
- Yii2
+ - Asserts
diff --git a/tests/functional/ContactFormCest.php b/tests/functional/ContactFormCest.php
index ad8167865..f1ccaf18f 100644
--- a/tests/functional/ContactFormCest.php
+++ b/tests/functional/ContactFormCest.php
@@ -1,15 +1,15 @@
amOnPage(['site/contact']);
+ $I->amOnRoute('site/contact');
}
public function openContactPage(\FunctionalTester $I)
{
- $I->see('Contact', 'h1');
+ $I->see('Contact', 'h1');
}
public function submitEmptyForm(\FunctionalTester $I)
@@ -38,7 +38,7 @@ public function submitFormWithIncorrectEmail(\FunctionalTester $I)
$I->see('Email is not a valid email address.');
$I->dontSee('Subject cannot be blank', '.help-inline');
$I->dontSee('Body cannot be blank', '.help-inline');
- $I->dontSee('The verification code is incorrect', '.help-inline');
+ $I->dontSee('The verification code is incorrect', '.help-inline');
}
public function submitFormSuccessfully(\FunctionalTester $I)
@@ -52,6 +52,6 @@ public function submitFormSuccessfully(\FunctionalTester $I)
]);
$I->seeEmailIsSent();
$I->dontSeeElement('#contact-form');
- $I->see('Thank you for contacting us. We will respond to you as soon as possible.');
+ $I->see('Thank you for contacting us. We will respond to you as soon as possible.');
}
}
diff --git a/tests/functional/LoginFormCest.php b/tests/functional/LoginFormCest.php
index 7a83a27d6..a1545a706 100644
--- a/tests/functional/LoginFormCest.php
+++ b/tests/functional/LoginFormCest.php
@@ -10,7 +10,6 @@ public function _before(\FunctionalTester $I)
public function openLoginPage(\FunctionalTester $I)
{
$I->see('Login', 'h1');
-
}
// demonstrates `amLoggedInAs` method
@@ -54,6 +53,6 @@ public function loginSuccessfully(\FunctionalTester $I)
'LoginForm[password]' => 'admin',
]);
$I->see('Logout (admin)');
- $I->dontSeeElement('form#login-form');
+ $I->dontSeeElement('form#login-form');
}
-}
\ No newline at end of file
+}
diff --git a/tests/unit.suite.yml b/tests/unit.suite.yml
index d2e6622f8..c14e49c37 100644
--- a/tests/unit.suite.yml
+++ b/tests/unit.suite.yml
@@ -3,7 +3,7 @@
# suite for unit (internal) tests.
# RUN `build` COMMAND AFTER ADDING/REMOVING MODULES.
-class_name: UnitTester
+actor: UnitTester
modules:
enabled:
- Asserts
diff --git a/tests/unit/models/ContactFormTest.php b/tests/unit/models/ContactFormTest.php
index 93313e4a6..1bb1bb2d0 100644
--- a/tests/unit/models/ContactFormTest.php
+++ b/tests/unit/models/ContactFormTest.php
@@ -24,18 +24,18 @@ public function testEmailIsSentOnContact()
'verifyCode' => 'testme',
];
- expect_that($model->contact('admin@example.com'));
+ verify($model->contact('admin@example.com'))->notEmpty();
// using Yii2 module actions to check email was sent
$this->tester->seeEmailIsSent();
/** @var MessageInterface $emailMessage */
$emailMessage = $this->tester->grabLastSentEmail();
- expect('valid email is sent', $emailMessage)->isInstanceOf('yii\mail\MessageInterface');
- expect($emailMessage->getTo())->hasKey('admin@example.com');
- expect($emailMessage->getFrom())->hasKey('noreply@example.com');
- expect($emailMessage->getReplyTo())->hasKey('tester@example.com');
- expect($emailMessage->getSubject())->equals('very important letter subject');
- expect($emailMessage->toString())->stringContainsString('body of current message');
+ verify($emailMessage)->instanceOf('yii\mail\MessageInterface');
+ verify($emailMessage->getTo())->arrayHasKey('admin@example.com');
+ verify($emailMessage->getFrom())->arrayHasKey('noreply@example.com');
+ verify($emailMessage->getReplyTo())->arrayHasKey('tester@example.com');
+ verify($emailMessage->getSubject())->equals('very important letter subject');
+ verify($emailMessage->toString())->stringContainsString('body of current message');
}
}
diff --git a/tests/unit/models/LoginFormTest.php b/tests/unit/models/LoginFormTest.php
index ecdb14512..6f96c2377 100644
--- a/tests/unit/models/LoginFormTest.php
+++ b/tests/unit/models/LoginFormTest.php
@@ -20,8 +20,8 @@ public function testLoginNoUser()
'password' => 'not_existing_password',
]);
- expect_not($this->model->login());
- expect_that(\Yii::$app->user->isGuest);
+ verify($this->model->login())->false();
+ verify(\Yii::$app->user->isGuest)->true();
}
public function testLoginWrongPassword()
@@ -31,9 +31,9 @@ public function testLoginWrongPassword()
'password' => 'wrong_password',
]);
- expect_not($this->model->login());
- expect_that(\Yii::$app->user->isGuest);
- expect($this->model->errors)->hasKey('password');
+ verify($this->model->login())->false();
+ verify(\Yii::$app->user->isGuest)->true();
+ verify($this->model->errors)->arrayHasKey('password');
}
public function testLoginCorrect()
@@ -43,9 +43,8 @@ public function testLoginCorrect()
'password' => 'demo',
]);
- expect_that($this->model->login());
- expect_not(\Yii::$app->user->isGuest);
- expect($this->model->errors)->hasntKey('password');
+ verify($this->model->login())->true();
+ verify(\Yii::$app->user->isGuest)->false();
+ verify($this->model->errors)->arrayHasNotKey('password');
}
-
}
diff --git a/tests/unit/models/UserTest.php b/tests/unit/models/UserTest.php
index cb612785f..3db9772a3 100644
--- a/tests/unit/models/UserTest.php
+++ b/tests/unit/models/UserTest.php
@@ -8,37 +8,36 @@ class UserTest extends \Codeception\Test\Unit
{
public function testFindUserById()
{
- expect_that($user = User::findIdentity(100));
- expect($user->username)->equals('admin');
+ verify($user = User::findIdentity(100))->notEmpty();
+ verify($user->username)->equals('admin');
- expect_not(User::findIdentity(999));
+ verify(User::findIdentity(999))->empty();
}
public function testFindUserByAccessToken()
{
- expect_that($user = User::findIdentityByAccessToken('100-token'));
- expect($user->username)->equals('admin');
+ verify($user = User::findIdentityByAccessToken('100-token'))->notEmpty();
+ verify($user->username)->equals('admin');
- expect_not(User::findIdentityByAccessToken('non-existing'));
+ verify(User::findIdentityByAccessToken('non-existing'))->empty();
}
public function testFindUserByUsername()
{
- expect_that($user = User::findByUsername('admin'));
- expect_not(User::findByUsername('not-admin'));
+ verify($user = User::findByUsername('admin'))->notEmpty();
+ verify(User::findByUsername('not-admin'))->empty();
}
/**
* @depends testFindUserByUsername
*/
- public function testValidateUser($user)
+ public function testValidateUser()
{
$user = User::findByUsername('admin');
- expect_that($user->validateAuthKey('test100key'));
- expect_not($user->validateAuthKey('test102key'));
+ verify($user->validateAuthKey('test100key'))->notEmpty();
+ verify($user->validateAuthKey('test102key'))->empty();
- expect_that($user->validatePassword('admin'));
- expect_not($user->validatePassword('123456'));
+ verify($user->validatePassword('admin'))->notEmpty();
+ verify($user->validatePassword('123456'))->empty();
}
-
}
diff --git a/tests/unit/widgets/AlertTest.php b/tests/unit/widgets/AlertTest.php
new file mode 100644
index 000000000..af2db5d21
--- /dev/null
+++ b/tests/unit/widgets/AlertTest.php
@@ -0,0 +1,263 @@
+session->setFlash('error', $message);
+
+ $renderingResult = Alert::widget();
+
+ verify($renderingResult)->stringContainsString($message);
+ verify($renderingResult)->stringContainsString('alert-danger');
+
+ verify($renderingResult)->stringNotContainsString('alert-success');
+ verify($renderingResult)->stringNotContainsString('alert-info');
+ verify($renderingResult)->stringNotContainsString('alert-warning');
+ }
+
+ public function testMultipleErrorMessages()
+ {
+ $firstMessage = 'This is the first error message';
+ $secondMessage = 'This is the second error message';
+
+ Yii::$app->session->setFlash('error', [$firstMessage, $secondMessage]);
+
+ $renderingResult = Alert::widget();
+
+ verify($renderingResult)->stringContainsString($firstMessage);
+ verify($renderingResult)->stringContainsString($secondMessage);
+ verify($renderingResult)->stringContainsString('alert-danger');
+
+ verify($renderingResult)->stringNotContainsString('alert-success');
+ verify($renderingResult)->stringNotContainsString('alert-info');
+ verify($renderingResult)->stringNotContainsString('alert-warning');
+ }
+
+ public function testSingleDangerMessage()
+ {
+ $message = 'This is a danger message';
+
+ Yii::$app->session->setFlash('danger', $message);
+
+ $renderingResult = Alert::widget();
+
+ verify($renderingResult)->stringContainsString($message);
+ verify($renderingResult)->stringContainsString('alert-danger');
+
+ verify($renderingResult)->stringNotContainsString('alert-success');
+ verify($renderingResult)->stringNotContainsString('alert-info');
+ verify($renderingResult)->stringNotContainsString('alert-warning');
+ }
+
+ public function testMultipleDangerMessages()
+ {
+ $firstMessage = 'This is the first danger message';
+ $secondMessage = 'This is the second danger message';
+
+ Yii::$app->session->setFlash('danger', [$firstMessage, $secondMessage]);
+
+ $renderingResult = Alert::widget();
+
+ verify($renderingResult)->stringContainsString($firstMessage);
+ verify($renderingResult)->stringContainsString($secondMessage);
+ verify($renderingResult)->stringContainsString('alert-danger');
+
+ verify($renderingResult)->stringNotContainsString('alert-success');
+ verify($renderingResult)->stringNotContainsString('alert-info');
+ verify($renderingResult)->stringNotContainsString('alert-warning');
+ }
+
+ public function testSingleSuccessMessage()
+ {
+ $message = 'This is a success message';
+
+ Yii::$app->session->setFlash('success', $message);
+
+ $renderingResult = Alert::widget();
+
+ verify($renderingResult)->stringContainsString($message);
+ verify($renderingResult)->stringContainsString('alert-success');
+
+ verify($renderingResult)->stringNotContainsString('alert-danger');
+ verify($renderingResult)->stringNotContainsString('alert-info');
+ verify($renderingResult)->stringNotContainsString('alert-warning');
+ }
+
+ public function testMultipleSuccessMessages()
+ {
+ $firstMessage = 'This is the first danger message';
+ $secondMessage = 'This is the second danger message';
+
+ Yii::$app->session->setFlash('success', [$firstMessage, $secondMessage]);
+
+ $renderingResult = Alert::widget();
+
+ verify($renderingResult)->stringContainsString($firstMessage);
+ verify($renderingResult)->stringContainsString($secondMessage);
+ verify($renderingResult)->stringContainsString('alert-success');
+
+ verify($renderingResult)->stringNotContainsString('alert-danger');
+ verify($renderingResult)->stringNotContainsString('alert-info');
+ verify($renderingResult)->stringNotContainsString('alert-warning');
+ }
+
+ public function testSingleInfoMessage()
+ {
+ $message = 'This is an info message';
+
+ Yii::$app->session->setFlash('info', $message);
+
+ $renderingResult = Alert::widget();
+
+ verify($renderingResult)->stringContainsString($message);
+ verify($renderingResult)->stringContainsString('alert-info');
+
+ verify($renderingResult)->stringNotContainsString('alert-danger');
+ verify($renderingResult)->stringNotContainsString('alert-success');
+ verify($renderingResult)->stringNotContainsString('alert-warning');
+ }
+
+ public function testMultipleInfoMessages()
+ {
+ $firstMessage = 'This is the first info message';
+ $secondMessage = 'This is the second info message';
+
+ Yii::$app->session->setFlash('info', [$firstMessage, $secondMessage]);
+
+ $renderingResult = Alert::widget();
+
+ verify($renderingResult)->stringContainsString($firstMessage);
+ verify($renderingResult)->stringContainsString($secondMessage);
+ verify($renderingResult)->stringContainsString('alert-info');
+
+ verify($renderingResult)->stringNotContainsString('alert-danger');
+ verify($renderingResult)->stringNotContainsString('alert-success');
+ verify($renderingResult)->stringNotContainsString('alert-warning');
+ }
+
+ public function testSingleWarningMessage()
+ {
+ $message = 'This is a warning message';
+
+ Yii::$app->session->setFlash('warning', $message);
+
+ $renderingResult = Alert::widget();
+
+ verify($renderingResult)->stringContainsString($message);
+ verify($renderingResult)->stringContainsString('alert-warning');
+
+ verify($renderingResult)->stringNotContainsString('alert-danger');
+ verify($renderingResult)->stringNotContainsString('alert-success');
+ verify($renderingResult)->stringNotContainsString('alert-info');
+ }
+
+ public function testMultipleWarningMessages()
+ {
+ $firstMessage = 'This is the first warning message';
+ $secondMessage = 'This is the second warning message';
+
+ Yii::$app->session->setFlash('warning', [$firstMessage, $secondMessage]);
+
+ $renderingResult = Alert::widget();
+
+ verify($renderingResult)->stringContainsString($firstMessage);
+ verify($renderingResult)->stringContainsString($secondMessage);
+ verify($renderingResult)->stringContainsString('alert-warning');
+
+ verify($renderingResult)->stringNotContainsString('alert-danger');
+ verify($renderingResult)->stringNotContainsString('alert-success');
+ verify($renderingResult)->stringNotContainsString('alert-info');
+ }
+
+ public function testSingleMixedMessages()
+ {
+ $errorMessage = 'This is an error message';
+ $dangerMessage = 'This is a danger message';
+ $successMessage = 'This is a success message';
+ $infoMessage = 'This is a info message';
+ $warningMessage = 'This is a warning message';
+
+ Yii::$app->session->setFlash('error', $errorMessage);
+ Yii::$app->session->setFlash('danger', $dangerMessage);
+ Yii::$app->session->setFlash('success', $successMessage);
+ Yii::$app->session->setFlash('info', $infoMessage);
+ Yii::$app->session->setFlash('warning', $warningMessage);
+
+ $renderingResult = Alert::widget();
+
+ verify($renderingResult)->stringContainsString($errorMessage);
+ verify($renderingResult)->stringContainsString($dangerMessage);
+ verify($renderingResult)->stringContainsString($successMessage);
+ verify($renderingResult)->stringContainsString($infoMessage);
+ verify($renderingResult)->stringContainsString($warningMessage);
+
+ verify($renderingResult)->stringContainsString('alert-danger');
+ verify($renderingResult)->stringContainsString('alert-success');
+ verify($renderingResult)->stringContainsString('alert-info');
+ verify($renderingResult)->stringContainsString('alert-warning');
+ }
+
+ public function testMultipleMixedMessages()
+ {
+ $firstErrorMessage = 'This is the first error message';
+ $secondErrorMessage = 'This is the second error message';
+ $firstDangerMessage = 'This is the first danger message';
+ $secondDangerMessage = 'This is the second';
+ $firstSuccessMessage = 'This is the first success message';
+ $secondSuccessMessage = 'This is the second success message';
+ $firstInfoMessage = 'This is the first info message';
+ $secondInfoMessage = 'This is the second info message';
+ $firstWarningMessage = 'This is the first warning message';
+ $secondWarningMessage = 'This is the second warning message';
+
+ Yii::$app->session->setFlash('error', [$firstErrorMessage, $secondErrorMessage]);
+ Yii::$app->session->setFlash('danger', [$firstDangerMessage, $secondDangerMessage]);
+ Yii::$app->session->setFlash('success', [$firstSuccessMessage, $secondSuccessMessage]);
+ Yii::$app->session->setFlash('info', [$firstInfoMessage, $secondInfoMessage]);
+ Yii::$app->session->setFlash('warning', [$firstWarningMessage, $secondWarningMessage]);
+
+ $renderingResult = Alert::widget();
+
+ verify($renderingResult)->stringContainsString($firstErrorMessage);
+ verify($renderingResult)->stringContainsString($secondErrorMessage);
+ verify($renderingResult)->stringContainsString($firstDangerMessage);
+ verify($renderingResult)->stringContainsString($secondDangerMessage);
+ verify($renderingResult)->stringContainsString($firstSuccessMessage);
+ verify($renderingResult)->stringContainsString($secondSuccessMessage);
+ verify($renderingResult)->stringContainsString($firstInfoMessage);
+ verify($renderingResult)->stringContainsString($secondInfoMessage);
+ verify($renderingResult)->stringContainsString($firstWarningMessage);
+ verify($renderingResult)->stringContainsString($secondWarningMessage);
+
+ verify($renderingResult)->stringContainsString('alert-danger');
+ verify($renderingResult)->stringContainsString('alert-success');
+ verify($renderingResult)->stringContainsString('alert-info');
+ verify($renderingResult)->stringContainsString('alert-warning');
+ }
+
+ public function testFlashIntegrity()
+ {
+ $errorMessage = 'This is an error message';
+ $unrelatedMessage = 'This is a message that is not related to the alert widget';
+
+ Yii::$app->session->setFlash('error', $errorMessage);
+ Yii::$app->session->setFlash('unrelated', $unrelatedMessage);
+
+ Alert::widget();
+
+ // Simulate redirect
+ Yii::$app->session->close();
+ Yii::$app->session->open();
+
+ verify(Yii::$app->session->getFlash('error'))->empty();
+ verify(Yii::$app->session->getFlash('unrelated'))->equals($unrelatedMessage);
+ }
+}
diff --git a/vagrant/provision/once-as-root.sh b/vagrant/provision/once-as-root.sh
index 75cbf5a2c..1d2917016 100644
--- a/vagrant/provision/once-as-root.sh
+++ b/vagrant/provision/once-as-root.sh
@@ -70,7 +70,7 @@ info "Removing default site configuration"
rm /etc/nginx/sites-enabled/default
echo "Done!"
-info "Initailize databases for MySQL"
+info "Initialize databases for MySQL"
mysql <<< 'CREATE DATABASE yii2basic'
mysql <<< 'CREATE DATABASE yii2basic_test'
echo "Done!"
diff --git a/views/layouts/main.php b/views/layouts/main.php
index 87dfdcbc9..c204435c0 100644
--- a/views/layouts/main.php
+++ b/views/layouts/main.php
@@ -1,77 +1,79 @@
registerCsrfMetaTags();
+$this->registerMetaTag(['charset' => Yii::$app->charset], 'charset');
+$this->registerMetaTag(['name' => 'viewport', 'content' => 'width=device-width, initial-scale=1, shrink-to-fit=no']);
+$this->registerMetaTag(['name' => 'description', 'content' => $this->params['meta_description'] ?? '']);
+$this->registerMetaTag(['name' => 'keywords', 'content' => $this->params['meta_keywords'] ?? '']);
+$this->registerLinkTag(['rel' => 'icon', 'type' => 'image/x-icon', 'href' => Yii::getAlias('@web/favicon.ico')]);
?>
beginPage() ?>
-
+
-
-
-
- registerCsrfMetaTags() ?>
= Html::encode($this->title) ?>
head() ?>
-
+
beginBody() ?>
-
+
+
- = Breadcrumbs::widget([
- 'links' => isset($this->params['breadcrumbs']) ? $this->params['breadcrumbs'] : [],
- ]) ?>
+ params['breadcrumbs'])): ?>
+ = Breadcrumbs::widget(['links' => $this->params['breadcrumbs']]) ?>
+
= Alert::widget() ?>
= $content ?>
-
+
-