Merge branch 'develop'

This commit is contained in:
ErickSkrauch 2019-03-10 03:23:27 +03:00
commit bc8cd305ac
261 changed files with 2282 additions and 2259 deletions

4
.gitignore vendored
View File

@ -23,3 +23,7 @@ npm-debug*
# PHP-CS-Fixer # PHP-CS-Fixer
.php_cs .php_cs
.php_cs.cache .php_cs.cache
# Codeception
codeception.yml
*/codeception.yml

View File

@ -47,9 +47,9 @@ test backend:
- sudo rm /usr/local/etc/php/conf.d/docker-php-ext-xdebug.ini - sudo rm /usr/local/etc/php/conf.d/docker-php-ext-xdebug.ini
script: script:
- composer install - composer install
- php tests/codeception/bin/yii rbac/generate - php yii rbac/generate
- ./docker/php/wait-for-it.sh "${DB_HOST}:3306" -s -t 0 -- "php tests/codeception/bin/yii migrate/up --interactive=0" - ./docker/php/wait-for-it.sh "${DB_HOST}:3306" -s -t 0 -- "php yii migrate/up --interactive=0"
- vendor/bin/codecept run -c tests - vendor/bin/codecept run
test frontend: test frontend:
image: node:9.2.1-alpine image: node:9.2.1-alpine

View File

@ -5,11 +5,11 @@ $finder = \PhpCsFixer\Finder::create()
->exclude('docker') ->exclude('docker')
->exclude('frontend') ->exclude('frontend')
->notPath('common/emails/views') ->notPath('common/emails/views')
->notPath('common/mail/layouts')
->notPath('/.*\/runtime/') ->notPath('/.*\/runtime/')
->notPath('autocompletion.php') ->notPath('autocompletion.php')
->notPath('tests/codeception/_output') ->notPath('/.*\/tests\/_output/')
->notPath('/tests\/codeception\/.*\/_output/') ->notPath('/.*\/tests\/_support\/_generated/')
->notPath('/tests\/codeception\/.*\/_support\/_generated/')
->name('yii'); ->name('yii');
return \Ely\CS\Config::create() return \Ely\CS\Config::create()

26
api/codeception.dist.yml Normal file
View File

@ -0,0 +1,26 @@
namespace: api\tests
actor_suffix: Tester
paths:
tests: tests
log: tests/_output
data: tests/_data
helpers: tests/_support
settings:
bootstrap: _bootstrap.php
colors: true
memory_limit: 1024M
coverage:
enabled: true
remote: true
whitelist:
include:
- ./*
exclude:
- aop/*
- config/*
- runtime/*
- tests/*
- web/*
- codeception.dist.yml
- codeception.yml
c3url: 'http://localhost/api/web/index.php'

View File

@ -12,7 +12,7 @@ interface IdentityInterface extends \yii\web\IdentityInterface {
* @throws \yii\web\UnauthorizedHttpException * @throws \yii\web\UnauthorizedHttpException
* @return IdentityInterface * @return IdentityInterface
*/ */
public static function findIdentityByAccessToken($token, $type = null): IdentityInterface; public static function findIdentityByAccessToken($token, $type = null): self;
/** /**
* Этот метод используется для получения токена, к которому привязаны права. * Этот метод используется для получения токена, к которому привязаны права.

View File

@ -1,7 +1,4 @@
<?php <?php
use api\components\ReCaptcha\Validator;
use GuzzleHttp\Client;
return [ return [
'components' => [ 'components' => [
'user' => [ 'user' => [
@ -12,18 +9,13 @@ return [
'secret' => 'private-key', 'secret' => 'private-key',
], ],
], ],
'modules' => [
'authserver' => [
'host' => 'localhost',
],
],
'params' => [ 'params' => [
'authserverHost' => 'authserver.ely.by', 'authserverHost' => 'localhost',
], ],
'container' => [ 'container' => [
'definitions' => [ 'definitions' => [
Validator::class => function() { api\components\ReCaptcha\Validator::class => function() {
return new class(new Client()) extends Validator { return new class(new GuzzleHttp\Client()) extends api\components\ReCaptcha\Validator {
protected function validateValue($value) { protected function validateValue($value) {
return null; return null;
} }

View File

@ -1,15 +1,12 @@
<?php <?php
$params = array_merge(
require __DIR__ . '/../../common/config/params.php',
require __DIR__ . '/params.php'
);
return [ return [
'id' => 'accounts-site-api', 'id' => 'accounts-site-api',
'basePath' => dirname(__DIR__), 'basePath' => dirname(__DIR__),
'bootstrap' => ['log', 'authserver', 'internal'], 'bootstrap' => ['log', 'authserver', 'internal', 'mojang'],
'controllerNamespace' => 'api\controllers', 'controllerNamespace' => 'api\controllers',
'params' => $params, 'params' => [
'authserverHost' => getenv('AUTHSERVER_HOST'),
],
'components' => [ 'components' => [
'user' => [ 'user' => [
'class' => api\components\User\Component::class, 'class' => api\components\User\Component::class,
@ -79,10 +76,7 @@ return [
], ],
], ],
'modules' => [ 'modules' => [
'authserver' => [ 'authserver' => api\modules\authserver\Module::class,
'class' => api\modules\authserver\Module::class,
'host' => $params['authserverHost'],
],
'session' => api\modules\session\Module::class, 'session' => api\modules\session\Module::class,
'mojang' => api\modules\mojang\Module::class, 'mojang' => api\modules\mojang\Module::class,
'internal' => api\modules\internal\Module::class, 'internal' => api\modules\internal\Module::class,

View File

@ -1,4 +0,0 @@
<?php
return [
'authserverHost' => getenv('AUTHSERVER_HOST'),
];

View File

@ -1,7 +1,4 @@
<?php <?php
/**
* @var array $params
*/
return [ return [
// Oauth module routes // Oauth module routes
'/oauth2/v1/<action>' => 'oauth/authorization/<action>', '/oauth2/v1/<action>' => 'oauth/authorization/<action>',
@ -46,8 +43,4 @@ return [
'/mojang/profiles/<username>' => 'mojang/api/uuid-by-username', '/mojang/profiles/<username>' => 'mojang/api/uuid-by-username',
'/mojang/profiles/<uuid>/names' => 'mojang/api/usernames-by-uuid', '/mojang/profiles/<uuid>/names' => 'mojang/api/usernames-by-uuid',
'POST /mojang/profiles' => 'mojang/api/uuids-by-usernames', 'POST /mojang/profiles' => 'mojang/api/uuids-by-usernames',
"//{$params['authserverHost']}/mojang/api/users/profiles/minecraft/<username>" => 'mojang/api/uuid-by-username',
"//{$params['authserverHost']}/mojang/api/user/profiles/<uuid>/names" => 'mojang/api/usernames-by-uuid',
"POST //{$params['authserverHost']}/mojang/api/profiles/minecraft" => 'mojang/api/uuids-by-usernames',
]; ];

View File

@ -15,9 +15,9 @@ use yii\web\NotFoundHttpException;
class DefaultController extends Controller { class DefaultController extends Controller {
public function behaviors(): array { public function behaviors(): array {
$paramsCallback = function() { $paramsCallback = function(): array {
$id = Yii::$app->request->get('id'); $id = (int)Yii::$app->request->get('id');
if ($id === null) { if ($id === 0) {
$identity = Yii::$app->user->getIdentity(); $identity = Yii::$app->user->getIdentity();
if ($identity !== null) { if ($identity !== null) {
$account = $identity->getAccount(); $account = $identity->getAccount();
@ -132,7 +132,7 @@ class DefaultController extends Controller {
return (new TwoFactorAuthInfo($this->findAccount($id)))->getCredentials(); return (new TwoFactorAuthInfo($this->findAccount($id)))->getCredentials();
} }
public function bindActionParams($action, $params) { public function bindActionParams($action, $params): array {
if (!isset($params['id'])) { if (!isset($params['id'])) {
/** @noinspection NullPointerExceptionInspection */ /** @noinspection NullPointerExceptionInspection */
$account = Yii::$app->user->getIdentity()->getAccount(); $account = Yii::$app->user->getIdentity()->getAccount();
@ -145,7 +145,13 @@ class DefaultController extends Controller {
} }
private function findAccount(int $id): Account { private function findAccount(int $id): Account {
$account = Account::findOne($id); if ($id === 0) {
/** @noinspection NullPointerExceptionInspection */
$account = Yii::$app->user->getIdentity()->getAccount();
} else {
$account = Account::findOne($id);
}
if ($account === null) { if ($account === null) {
throw new NotFoundHttpException(); throw new NotFoundHttpException();
} }

View File

@ -3,7 +3,7 @@ namespace api\modules\accounts\models;
use api\aop\annotations\CollectModelMetrics; use api\aop\annotations\CollectModelMetrics;
use yii\base\ErrorException; use yii\base\ErrorException;
use const \common\LATEST_RULES_VERSION; use const common\LATEST_RULES_VERSION;
class AcceptRulesForm extends AccountActionForm { class AcceptRulesForm extends AccountActionForm {

View File

@ -1,9 +1,10 @@
<?php <?php
declare(strict_types=1);
namespace api\modules\authserver; namespace api\modules\authserver;
use Yii; use Yii;
use yii\base\BootstrapInterface; use yii\base\BootstrapInterface;
use yii\base\InvalidConfigException;
use yii\web\NotFoundHttpException; use yii\web\NotFoundHttpException;
class Module extends \yii\base\Module implements BootstrapInterface { class Module extends \yii\base\Module implements BootstrapInterface {
@ -12,18 +13,6 @@ class Module extends \yii\base\Module implements BootstrapInterface {
public $defaultRoute = 'index'; public $defaultRoute = 'index';
/**
* @var string базовый домен, запросы на который этот модуль должен обрабатывать
*/
public $host = 'authserver.ely.by';
public function init() {
parent::init();
if ($this->host === null) {
throw new InvalidConfigException('base domain must be specified');
}
}
public function beforeAction($action) { public function beforeAction($action) {
if (!parent::beforeAction($action)) { if (!parent::beforeAction($action)) {
return false; return false;
@ -35,11 +24,12 @@ class Module extends \yii\base\Module implements BootstrapInterface {
} }
/** /**
* @param \yii\base\Application $app the application currently running * @param \yii\base\Application $app
*/ */
public function bootstrap($app) { public function bootstrap($app) {
$legacyHost = $app->params['authserverHost'];
$app->getUrlManager()->addRules([ $app->getUrlManager()->addRules([
"//$this->host/$this->id/auth/<action>" => "$this->id/authentication/<action>", "//{$legacyHost}/authserver/auth/<action>" => "{$this->id}/authentication/<action>",
], false); ], false);
} }
@ -59,7 +49,7 @@ class Module extends \yii\base\Module implements BootstrapInterface {
* @throws NotFoundHttpException * @throws NotFoundHttpException
*/ */
protected function checkHost() { protected function checkHost() {
if (parse_url(Yii::$app->request->getHostInfo(), PHP_URL_HOST) !== $this->host) { if (parse_url(Yii::$app->request->getHostInfo(), PHP_URL_HOST) !== Yii::$app->params['authserverHost']) {
throw new NotFoundHttpException(); throw new NotFoundHttpException();
} }
} }

View File

@ -42,9 +42,7 @@ class RefreshTokenForm extends ApiForm {
$accessToken->refreshPrimaryKeyValue(); $accessToken->refreshPrimaryKeyValue();
$accessToken->update(); $accessToken->update();
$dataModel = new AuthenticateData($accessToken); return new AuthenticateData($accessToken);
return $dataModel;
} }
} }

View File

@ -1,10 +1,26 @@
<?php <?php
declare(strict_types=1);
namespace api\modules\mojang; namespace api\modules\mojang;
class Module extends \yii\base\Module { use yii\base\BootstrapInterface;
class Module extends \yii\base\Module implements BootstrapInterface {
public $id = 'mojang'; public $id = 'mojang';
public $defaultRoute = 'api'; public $defaultRoute = 'api';
/**
* @param \yii\base\Application $app
*/
public function bootstrap($app): void {
$legacyHost = $app->params['authserverHost'];
$app->getUrlManager()->addRules([
"//{$legacyHost}/mojang/api/users/profiles/minecraft/<username>" => "{$this->id}/api/uuid-by-username",
"//{$legacyHost}/mojang/api/user/profiles/<uuid>/names" => "{$this->id}/api/usernames-by-uuid",
"POST //{$legacyHost}/mojang/api/profiles/minecraft" => "{$this->id}/api/uuids-by-usernames",
]);
}
} }

View File

@ -55,7 +55,10 @@ class AuthorizationController extends Controller {
} }
private function createOauthProcess(): OauthProcess { private function createOauthProcess(): OauthProcess {
return new OauthProcess(Yii::$app->oauth->authServer); $server = Yii::$app->oauth->authServer;
$server->setRequest(null); // Enforce request recreation (test environment bug)
return new OauthProcess($server);
} }
} }

View File

@ -90,7 +90,10 @@ class OauthClientForm {
} }
protected function isClientExists(string $id): bool { protected function isClientExists(string $id): bool {
return OauthClient::find()->andWhere(['id' => $id])->exists(); return OauthClient::find()
->includeDeleted()
->andWhere(['id' => $id])
->exists();
} }
} }

3
api/tests/.gitignore vendored Normal file
View File

@ -0,0 +1,3 @@
functional.suite.yml
unit.suite.yml
_support/_generated

10
api/tests/_bootstrap.php Normal file
View File

@ -0,0 +1,10 @@
<?php
defined('YII_DEBUG') || define('YII_DEBUG', true);
defined('YII_ENV') || define('YII_ENV', 'test');
defined('YII_APP_BASE_PATH') || define('YII_APP_BASE_PATH', __DIR__ . '/../../');
require_once YII_APP_BASE_PATH . '/vendor/autoload.php';
require_once YII_APP_BASE_PATH . '/vendor/yiisoft/yii2/Yii.php';
require_once YII_APP_BASE_PATH . '/common/config/bootstrap.php';
require_once __DIR__ . '/../config/bootstrap.php';

View File

@ -1,14 +1,14 @@
<?php <?php
namespace tests\codeception\api\_pages; namespace api\tests\_pages;
class AccountsRoute extends BasePage { class AccountsRoute extends BasePage {
public function get(int $accountId) { public function get(int $accountId) {
$this->getActor()->sendGET("/v1/accounts/{$accountId}"); $this->getActor()->sendGET("/api/v1/accounts/{$accountId}");
} }
public function changePassword(int $accountId, $currentPassword = null, $newPassword = null, $newRePassword = null) { public function changePassword(int $accountId, $currentPassword = null, $newPassword = null, $newRePassword = null) {
$this->getActor()->sendPOST("/v1/accounts/{$accountId}/password", [ $this->getActor()->sendPOST("/api/v1/accounts/{$accountId}/password", [
'password' => $currentPassword, 'password' => $currentPassword,
'newPassword' => $newPassword, 'newPassword' => $newPassword,
'newRePassword' => $newRePassword, 'newRePassword' => $newRePassword,
@ -16,65 +16,65 @@ class AccountsRoute extends BasePage {
} }
public function changeUsername(int $accountId, $currentPassword = null, $newUsername = null) { public function changeUsername(int $accountId, $currentPassword = null, $newUsername = null) {
$this->getActor()->sendPOST("/v1/accounts/{$accountId}/username", [ $this->getActor()->sendPOST("/api/v1/accounts/{$accountId}/username", [
'password' => $currentPassword, 'password' => $currentPassword,
'username' => $newUsername, 'username' => $newUsername,
]); ]);
} }
public function changeEmailInitialize(int $accountId, $password = '') { public function changeEmailInitialize(int $accountId, $password = '') {
$this->getActor()->sendPOST("/v1/accounts/{$accountId}/email-verification", [ $this->getActor()->sendPOST("/api/v1/accounts/{$accountId}/email-verification", [
'password' => $password, 'password' => $password,
]); ]);
} }
public function changeEmailSubmitNewEmail(int $accountId, $key = null, $email = null) { public function changeEmailSubmitNewEmail(int $accountId, $key = null, $email = null) {
$this->getActor()->sendPOST("/v1/accounts/{$accountId}/new-email-verification", [ $this->getActor()->sendPOST("/api/v1/accounts/{$accountId}/new-email-verification", [
'key' => $key, 'key' => $key,
'email' => $email, 'email' => $email,
]); ]);
} }
public function changeEmail(int $accountId, $key = null) { public function changeEmail(int $accountId, $key = null) {
$this->getActor()->sendPOST("/v1/accounts/{$accountId}/email", [ $this->getActor()->sendPOST("/api/v1/accounts/{$accountId}/email", [
'key' => $key, 'key' => $key,
]); ]);
} }
public function changeLanguage(int $accountId, $lang = null) { public function changeLanguage(int $accountId, $lang = null) {
$this->getActor()->sendPOST("/v1/accounts/{$accountId}/language", [ $this->getActor()->sendPOST("/api/v1/accounts/{$accountId}/language", [
'lang' => $lang, 'lang' => $lang,
]); ]);
} }
public function acceptRules(int $accountId) { public function acceptRules(int $accountId) {
$this->getActor()->sendPOST("/v1/accounts/{$accountId}/rules"); $this->getActor()->sendPOST("/api/v1/accounts/{$accountId}/rules");
} }
public function getTwoFactorAuthCredentials(int $accountId) { public function getTwoFactorAuthCredentials(int $accountId) {
$this->getActor()->sendGET("/v1/accounts/{$accountId}/two-factor-auth"); $this->getActor()->sendGET("/api/v1/accounts/{$accountId}/two-factor-auth");
} }
public function enableTwoFactorAuth(int $accountId, $totp = null, $password = null) { public function enableTwoFactorAuth(int $accountId, $totp = null, $password = null) {
$this->getActor()->sendPOST("/v1/accounts/{$accountId}/two-factor-auth", [ $this->getActor()->sendPOST("/api/v1/accounts/{$accountId}/two-factor-auth", [
'totp' => $totp, 'totp' => $totp,
'password' => $password, 'password' => $password,
]); ]);
} }
public function disableTwoFactorAuth(int $accountId, $totp = null, $password = null) { public function disableTwoFactorAuth(int $accountId, $totp = null, $password = null) {
$this->getActor()->sendDELETE("/v1/accounts/{$accountId}/two-factor-auth", [ $this->getActor()->sendDELETE("/api/v1/accounts/{$accountId}/two-factor-auth", [
'totp' => $totp, 'totp' => $totp,
'password' => $password, 'password' => $password,
]); ]);
} }
public function ban(int $accountId) { public function ban(int $accountId) {
$this->getActor()->sendPOST("/v1/accounts/{$accountId}/ban"); $this->getActor()->sendPOST("/api/v1/accounts/{$accountId}/ban");
} }
public function pardon(int $accountId) { public function pardon(int $accountId) {
$this->getActor()->sendDELETE("/v1/accounts/{$accountId}/ban"); $this->getActor()->sendDELETE("/api/v1/accounts/{$accountId}/ban");
} }
} }

View File

@ -1,5 +1,5 @@
<?php <?php
namespace tests\codeception\api\_pages; namespace api\tests\_pages;
class AuthenticationRoute extends BasePage { class AuthenticationRoute extends BasePage {
@ -21,22 +21,22 @@ class AuthenticationRoute extends BasePage {
$params['totp'] = $rememberMeOrToken; $params['totp'] = $rememberMeOrToken;
} }
$this->getActor()->sendPOST('/authentication/login', $params); $this->getActor()->sendPOST('/api/authentication/login', $params);
} }
public function logout() { public function logout() {
$this->getActor()->sendPOST('/authentication/logout'); $this->getActor()->sendPOST('/api/authentication/logout');
} }
public function forgotPassword($login = null, $token = null) { public function forgotPassword($login = null, $token = null) {
$this->getActor()->sendPOST('/authentication/forgot-password', [ $this->getActor()->sendPOST('/api/authentication/forgot-password', [
'login' => $login, 'login' => $login,
'totp' => $token, 'totp' => $token,
]); ]);
} }
public function recoverPassword($key = null, $newPassword = null, $newRePassword = null) { public function recoverPassword($key = null, $newPassword = null, $newRePassword = null) {
$this->getActor()->sendPOST('/authentication/recover-password', [ $this->getActor()->sendPOST('/api/authentication/recover-password', [
'key' => $key, 'key' => $key,
'newPassword' => $newPassword, 'newPassword' => $newPassword,
'newRePassword' => $newRePassword, 'newRePassword' => $newRePassword,
@ -44,7 +44,7 @@ class AuthenticationRoute extends BasePage {
} }
public function refreshToken($refreshToken = null) { public function refreshToken($refreshToken = null) {
$this->getActor()->sendPOST('/authentication/refresh-token', [ $this->getActor()->sendPOST('/api/authentication/refresh-token', [
'refresh_token' => $refreshToken, 'refresh_token' => $refreshToken,
]); ]);
} }

View File

@ -0,0 +1,26 @@
<?php
namespace api\tests\_pages;
class AuthserverRoute extends BasePage {
public function authenticate($params) {
$this->getActor()->sendPOST('/api/authserver/authentication/authenticate', $params);
}
public function refresh($params) {
$this->getActor()->sendPOST('/api/authserver/authentication/refresh', $params);
}
public function validate($params) {
$this->getActor()->sendPOST('/api/authserver/authentication/validate', $params);
}
public function invalidate($params) {
$this->getActor()->sendPOST('/api/authserver/authentication/invalidate', $params);
}
public function signout($params) {
$this->getActor()->sendPOST('/api/authserver/authentication/signout', $params);
}
}

View File

@ -1,7 +1,7 @@
<?php <?php
namespace tests\codeception\api\_pages; namespace api\tests\_pages;
use tests\codeception\api\FunctionalTester; use api\tests\FunctionalTester;
class BasePage { class BasePage {

View File

@ -0,0 +1,10 @@
<?php
namespace api\tests\_pages;
class IdentityInfoRoute extends BasePage {
public function info() {
$this->getActor()->sendGET('/api/account/v1/info');
}
}

View File

@ -0,0 +1,10 @@
<?php
namespace api\tests\_pages;
class InternalRoute extends BasePage {
public function info(string $param, string $value) {
$this->getActor()->sendGET('/api/internal/accounts/info', [$param => $value]);
}
}

View File

@ -1,19 +1,19 @@
<?php <?php
namespace tests\codeception\api\_pages; namespace api\tests\_pages;
class MojangApiRoute extends BasePage { class MojangApiRoute extends BasePage {
public function usernameToUuid($username, $at = null) { public function usernameToUuid($username, $at = null) {
$params = $at === null ? [] : ['at' => $at]; $params = $at === null ? [] : ['at' => $at];
$this->getActor()->sendGET("/mojang/profiles/{$username}", $params); $this->getActor()->sendGET("/api/mojang/profiles/{$username}", $params);
} }
public function usernamesByUuid($uuid) { public function usernamesByUuid($uuid) {
$this->getActor()->sendGET("/mojang/profiles/{$uuid}/names"); $this->getActor()->sendGET("/api/mojang/profiles/{$uuid}/names");
} }
public function uuidsByUsernames($uuids) { public function uuidsByUsernames($uuids) {
$this->getActor()->sendPOST('/mojang/profiles', $uuids); $this->getActor()->sendPOST('/api/mojang/profiles', $uuids);
} }
} }

View File

@ -0,0 +1,42 @@
<?php
namespace api\tests\_pages;
class OauthRoute extends BasePage {
public function validate(array $queryParams): void {
$this->getActor()->sendGET('/api/oauth2/v1/validate', $queryParams);
}
public function complete(array $queryParams = [], array $postParams = []): void {
$this->getActor()->sendPOST('/api/oauth2/v1/complete?' . http_build_query($queryParams), $postParams);
}
public function issueToken(array $postParams = []): void {
$this->getActor()->sendPOST('/api/oauth2/v1/token', $postParams);
}
public function createClient(string $type, array $postParams): void {
$this->getActor()->sendPOST('/api/v1/oauth2/' . $type, $postParams);
}
public function updateClient(string $clientId, array $params): void {
$this->getActor()->sendPUT('/api/v1/oauth2/' . $clientId, $params);
}
public function deleteClient(string $clientId): void {
$this->getActor()->sendDELETE('/api/v1/oauth2/' . $clientId);
}
public function resetClient(string $clientId, bool $regenerateSecret = false): void {
$this->getActor()->sendPOST("/api/v1/oauth2/{$clientId}/reset" . ($regenerateSecret ? '?regenerateSecret' : ''));
}
public function getClient(string $clientId): void {
$this->getActor()->sendGET("/api/v1/oauth2/{$clientId}");
}
public function getPerAccount(int $accountId): void {
$this->getActor()->sendGET("/api/v1/accounts/{$accountId}/oauth2/clients");
}
}

View File

@ -0,0 +1,10 @@
<?php
namespace api\tests\_pages;
class OptionsRoute extends BasePage {
public function get() {
$this->getActor()->sendGET('/api/options');
}
}

View File

@ -0,0 +1,26 @@
<?php
namespace api\tests\_pages;
class SessionServerRoute extends BasePage {
public function join($params) {
$this->getActor()->sendPOST('/api/minecraft/session/join', $params);
}
public function joinLegacy(array $params) {
$this->getActor()->sendGET('/api/minecraft/session/legacy/join', $params);
}
public function hasJoined(array $params) {
$this->getActor()->sendGET('/api/minecraft/session/hasJoined', $params);
}
public function hasJoinedLegacy(array $params) {
$this->getActor()->sendGET('/api/minecraft/session/legacy/hasJoined', $params);
}
public function profile($profileUuid) {
$this->getActor()->sendGET("/api/minecraft/session/profile/{$profileUuid}");
}
}

View File

@ -1,18 +1,18 @@
<?php <?php
namespace tests\codeception\api\_pages; namespace api\tests\_pages;
class SignupRoute extends BasePage { class SignupRoute extends BasePage {
public function register(array $registrationData) { public function register(array $registrationData) {
$this->getActor()->sendPOST('/signup', $registrationData); $this->getActor()->sendPOST('/api/signup', $registrationData);
} }
public function sendRepeatMessage($email = '') { public function sendRepeatMessage($email = '') {
$this->getActor()->sendPOST('/signup/repeat-message', ['email' => $email]); $this->getActor()->sendPOST('/api/signup/repeat-message', ['email' => $email]);
} }
public function confirm($key = '') { public function confirm($key = '') {
$this->getActor()->sendPOST('/signup/confirm', [ $this->getActor()->sendPOST('/api/signup/confirm', [
'key' => $key, 'key' => $key,
]); ]);
} }

View File

@ -1,34 +1,22 @@
<?php <?php
namespace tests\codeception\api; declare(strict_types=1);
namespace api\tests;
use api\tests\_generated\FunctionalTesterActions;
use Codeception\Actor; use Codeception\Actor;
use common\models\Account; use common\models\Account;
use InvalidArgumentException; use InvalidArgumentException;
use Yii; use Yii;
/**
* Inherited Methods
* @method void wantToTest($text)
* @method void wantTo($text)
* @method void execute($callable)
* @method void expectTo($prediction)
* @method void expect($prediction)
* @method void amGoingTo($argumentation)
* @method void am($role)
* @method void lookForwardTo($achieveValue)
* @method void comment($description)
* @method \Codeception\Lib\Friend haveFriend($name, $actorClass = NULL)
*
* @SuppressWarnings(PHPMD)
*/
class FunctionalTester extends Actor { class FunctionalTester extends Actor {
use _generated\FunctionalTesterActions; use FunctionalTesterActions;
public function amAuthenticated(string $asUsername = 'admin') { public function amAuthenticated(string $asUsername = 'admin') {
/** @var Account $account */ /** @var Account $account */
$account = Account::findOne(['username' => $asUsername]); $account = Account::findOne(['username' => $asUsername]);
if ($account === null) { if ($account === null) {
throw new InvalidArgumentException("Cannot find account for username \"$asUsername\""); throw new InvalidArgumentException("Cannot find account for username \"{$asUsername}\"");
} }
$result = Yii::$app->user->createJwtAuthenticationToken($account, false); $result = Yii::$app->user->createJwtAuthenticationToken($account, false);
@ -37,11 +25,12 @@ class FunctionalTester extends Actor {
return $account->id; return $account->id;
} }
public function notLoggedIn() { public function notLoggedIn(): void {
$this->haveHttpHeader('Authorization', null); $this->haveHttpHeader('Authorization', null);
Yii::$app->user->logout();
} }
public function canSeeAuthCredentials($expectRefresh = false) { public function canSeeAuthCredentials($expectRefresh = false): void {
$this->canSeeResponseJsonMatchesJsonPath('$.access_token'); $this->canSeeResponseJsonMatchesJsonPath('$.access_token');
$this->canSeeResponseJsonMatchesJsonPath('$.expires_in'); $this->canSeeResponseJsonMatchesJsonPath('$.expires_in');
if ($expectRefresh) { if ($expectRefresh) {

View File

@ -0,0 +1,12 @@
<?php
declare(strict_types=1);
namespace api\tests;
use api\tests\_generated\UnitTesterActions;
use Codeception\Actor;
class UnitTester extends Actor {
use UnitTesterActions;
}

View File

@ -0,0 +1,8 @@
<?php
use common\config\ConfigLoader;
use yii\helpers\ArrayHelper;
return ArrayHelper::merge(ConfigLoader::load('api'), [
]);

View File

@ -0,0 +1,8 @@
<?php
use common\config\ConfigLoader;
use yii\helpers\ArrayHelper;
return ArrayHelper::merge(ConfigLoader::load('api'), [
]);

View File

@ -0,0 +1,20 @@
suite_namespace: api\tests\functional
actor: FunctionalTester
modules:
enabled:
- Asserts
- Filesystem
- Yii2:
configFile: tests/config/functional.php
entryScript: /api/web/index.php
recreateApplication: true
transaction: false
- common\tests\_support\FixtureHelper
- common\tests\_support\Mockery
- REST:
depends: Yii2
- Redis:
host: redis
port: 6379
database: 0
cleanupBefore: 'test'

View File

@ -1,7 +1,8 @@
<?php <?php
namespace tests\codeception\api; namespace api\tests\functional;
use tests\codeception\api\_pages\SignupRoute; use api\tests\_pages\SignupRoute;
use api\tests\FunctionalTester;
class EmailConfirmationCest { class EmailConfirmationCest {

View File

@ -1,12 +1,12 @@
<?php <?php
namespace tests\codeception\api\functional; namespace api\tests\functional;
use tests\codeception\api\FunctionalTester; use api\tests\FunctionalTester;
class FeedbackCest { class FeedbackCest {
public function testFeedbackWithoutAuth(FunctionalTester $I) { public function testFeedbackWithoutAuth(FunctionalTester $I) {
$I->sendPOST('/feedback', [ $I->sendPOST('/api/feedback', [
'subject' => 'Test', 'subject' => 'Test',
'email' => 'email@ely.by', 'email' => 'email@ely.by',
'type' => 0, 'type' => 0,
@ -21,7 +21,7 @@ class FeedbackCest {
public function testFeedbackWithAuth(FunctionalTester $I) { public function testFeedbackWithAuth(FunctionalTester $I) {
$I->amAuthenticated(); $I->amAuthenticated();
$I->sendPOST('/feedback', [ $I->sendPOST('/api/feedback', [
'subject' => 'Test', 'subject' => 'Test',
'email' => 'email@ely.by', 'email' => 'email@ely.by',
'type' => 0, 'type' => 0,

View File

@ -1,8 +1,8 @@
<?php <?php
namespace codeception\api\functional; namespace api\tests\functional;
use tests\codeception\api\_pages\AuthenticationRoute; use api\tests\_pages\AuthenticationRoute;
use tests\codeception\api\FunctionalTester; use api\tests\FunctionalTester;
class ForgotPasswordCest { class ForgotPasswordCest {

View File

@ -1,8 +1,9 @@
<?php <?php
namespace tests\codeception\api; namespace api\tests\functional;
use api\tests\_pages\AuthenticationRoute;
use api\tests\FunctionalTester;
use OTPHP\TOTP; use OTPHP\TOTP;
use tests\codeception\api\_pages\AuthenticationRoute;
class LoginCest { class LoginCest {

View File

@ -1,7 +1,8 @@
<?php <?php
namespace tests\codeception\api; namespace api\tests\functional;
use tests\codeception\api\_pages\AuthenticationRoute; use api\tests\_pages\AuthenticationRoute;
use api\tests\FunctionalTester;
class LogoutCest { class LogoutCest {

View File

@ -1,8 +1,8 @@
<?php <?php
namespace codeception\api\functional; namespace api\tests\functional;
use tests\codeception\api\_pages\OptionsRoute; use api\tests\_pages\OptionsRoute;
use tests\codeception\api\FunctionalTester; use api\tests\FunctionalTester;
class OptionsCest { class OptionsCest {

View File

@ -1,9 +1,9 @@
<?php <?php
namespace codeception\api\functional; namespace api\tests\functional;
use tests\codeception\api\_pages\AccountsRoute; use api\tests\_pages\AccountsRoute;
use tests\codeception\api\_pages\AuthenticationRoute; use api\tests\_pages\AuthenticationRoute;
use tests\codeception\api\FunctionalTester; use api\tests\FunctionalTester;
class RecoverPasswordCest { class RecoverPasswordCest {

View File

@ -1,8 +1,8 @@
<?php <?php
namespace codeception\api\functional; namespace api\tests\functional;
use tests\codeception\api\_pages\AuthenticationRoute; use api\tests\_pages\AuthenticationRoute;
use tests\codeception\api\FunctionalTester; use api\tests\FunctionalTester;
class RefreshTokenCest { class RefreshTokenCest {

View File

@ -1,9 +1,9 @@
<?php <?php
namespace tests\codeception\api\functional; namespace api\tests\functional;
use api\tests\_pages\SignupRoute;
use api\tests\FunctionalTester;
use Codeception\Example; use Codeception\Example;
use tests\codeception\api\_pages\SignupRoute;
use tests\codeception\api\FunctionalTester;
class RegisterCest { class RegisterCest {

View File

@ -1,8 +1,8 @@
<?php <?php
namespace tests\codeception\api\functional; namespace api\tests\functional;
use tests\codeception\api\_pages\SignupRoute; use api\tests\_pages\SignupRoute;
use tests\codeception\api\FunctionalTester; use api\tests\FunctionalTester;
class RepeatAccountActivationCest { class RepeatAccountActivationCest {

View File

@ -1,13 +1,15 @@
<?php <?php
namespace tests\codeception\api\functional\_steps; declare(strict_types=1);
namespace api\tests\functional\_steps;
use api\tests\_pages\AuthserverRoute;
use api\tests\FunctionalTester;
use Ramsey\Uuid\Uuid; use Ramsey\Uuid\Uuid;
use tests\codeception\api\_pages\AuthserverRoute;
use tests\codeception\api\FunctionalTester;
class AuthserverSteps extends FunctionalTester { class AuthserverSteps extends FunctionalTester {
public function amAuthenticated(string $asUsername = 'admin', string $password = 'password_0') { public function amAuthenticated(string $asUsername = 'admin', string $password = 'password_0'): array {
$route = new AuthserverRoute($this); $route = new AuthserverRoute($this);
$clientToken = Uuid::uuid4()->toString(); $clientToken = Uuid::uuid4()->toString();
$route->authenticate([ $route->authenticate([

View File

@ -1,9 +1,9 @@
<?php <?php
namespace tests\codeception\api\functional\_steps; namespace api\tests\functional\_steps;
use api\components\OAuth2\Storage\ScopeStorage as S; use api\components\OAuth2\Storage\ScopeStorage as S;
use tests\codeception\api\_pages\OauthRoute; use api\tests\_pages\OauthRoute;
use tests\codeception\api\FunctionalTester; use api\tests\FunctionalTester;
class OauthSteps extends FunctionalTester { class OauthSteps extends FunctionalTester {

View File

@ -1,10 +1,10 @@
<?php <?php
namespace tests\codeception\api\functional\_steps; namespace api\tests\functional\_steps;
use api\tests\_pages\SessionServerRoute;
use api\tests\FunctionalTester;
use common\rbac\Permissions as P; use common\rbac\Permissions as P;
use Faker\Provider\Uuid; use Faker\Provider\Uuid;
use tests\codeception\api\_pages\SessionServerRoute;
use tests\codeception\api\FunctionalTester;
class SessionServerSteps extends FunctionalTester { class SessionServerSteps extends FunctionalTester {
@ -54,8 +54,8 @@ class SessionServerSteps extends FunctionalTester {
$decoded = json_decode(base64_decode($value), true); $decoded = json_decode(base64_decode($value), true);
$this->assertArrayHasKey('timestamp', $decoded); $this->assertArrayHasKey('timestamp', $decoded);
$this->assertArrayHasKey('textures', $decoded); $this->assertArrayHasKey('textures', $decoded);
$this->assertEquals($expectedUuid, $decoded['profileId']); $this->assertSame($expectedUuid, $decoded['profileId']);
$this->assertEquals($expectedUsername, $decoded['profileName']); $this->assertSame($expectedUsername, $decoded['profileName']);
$this->assertTrue($decoded['ely']); $this->assertTrue($decoded['ely']);
$textures = $decoded['textures']; $textures = $decoded['textures'];
$this->assertArrayHasKey('SKIN', $textures); $this->assertArrayHasKey('SKIN', $textures);

View File

@ -1,8 +1,8 @@
<?php <?php
namespace tests\codeception\api\functional\accounts; namespace api\tests\functional\accounts;
use tests\codeception\api\_pages\AccountsRoute; use api\tests\_pages\AccountsRoute;
use tests\codeception\api\FunctionalTester; use api\tests\FunctionalTester;
class AcceptRulesCest { class AcceptRulesCest {

View File

@ -1,10 +1,10 @@
<?php <?php
namespace tests\codeception\api\functional\accounts; namespace api\tests\functional\accounts;
use api\tests\_pages\AccountsRoute;
use api\tests\functional\_steps\OauthSteps;
use api\tests\FunctionalTester;
use common\rbac\Permissions as P; use common\rbac\Permissions as P;
use tests\codeception\api\_pages\AccountsRoute;
use tests\codeception\api\functional\_steps\OauthSteps;
use tests\codeception\api\FunctionalTester;
class BanCest { class BanCest {

View File

@ -1,8 +1,8 @@
<?php <?php
namespace tests\codeception\api\functional\accounts; namespace api\tests\functional\accounts;
use tests\codeception\api\_pages\AccountsRoute; use api\tests\_pages\AccountsRoute;
use tests\codeception\api\FunctionalTester; use api\tests\FunctionalTester;
class ChangeEmailConfirmNewEmailCest { class ChangeEmailConfirmNewEmailCest {

View File

@ -1,8 +1,8 @@
<?php <?php
namespace tests\codeception\api\functional\accounts; namespace api\tests\functional\accounts;
use tests\codeception\api\_pages\AccountsRoute; use api\tests\_pages\AccountsRoute;
use tests\codeception\api\FunctionalTester; use api\tests\FunctionalTester;
class ChangeEmailInitializeCest { class ChangeEmailInitializeCest {

View File

@ -1,9 +1,9 @@
<?php <?php
namespace tests\codeception\api\functional\accounts; namespace api\tests\functional\accounts;
use tests\codeception\api\_pages\AccountsRoute; use api\tests\_pages\AccountsRoute;
use tests\codeception\api\FunctionalTester; use api\tests\FunctionalTester;
use tests\codeception\common\helpers\Mock; use common\tests\helpers\Mock;
use yii\validators\EmailValidator; use yii\validators\EmailValidator;
class ChangeEmailSubmitNewEmailCest { class ChangeEmailSubmitNewEmailCest {

View File

@ -1,8 +1,8 @@
<?php <?php
namespace tests\codeception\api\functional\accounts; namespace api\tests\functional\accounts;
use tests\codeception\api\_pages\AccountsRoute; use api\tests\_pages\AccountsRoute;
use tests\codeception\api\FunctionalTester; use api\tests\FunctionalTester;
class ChangeLangCest { class ChangeLangCest {

View File

@ -1,11 +1,11 @@
<?php <?php
namespace tests\codeception\api\functional\accounts; namespace api\tests\functional\accounts;
use api\tests\_pages\AccountsRoute;
use api\tests\_pages\AuthenticationRoute;
use api\tests\functional\_steps\OauthSteps;
use api\tests\FunctionalTester;
use common\models\Account; use common\models\Account;
use tests\codeception\api\_pages\AccountsRoute;
use tests\codeception\api\_pages\AuthenticationRoute;
use tests\codeception\api\functional\_steps\OauthSteps;
use tests\codeception\api\FunctionalTester;
class ChangePasswordCest { class ChangePasswordCest {

View File

@ -1,10 +1,10 @@
<?php <?php
namespace tests\codeception\api\functional\accounts; namespace api\tests\functional\accounts;
use api\tests\_pages\AccountsRoute;
use api\tests\functional\_steps\OauthSteps;
use api\tests\FunctionalTester;
use common\models\Account; use common\models\Account;
use tests\codeception\api\_pages\AccountsRoute;
use tests\codeception\api\functional\_steps\OauthSteps;
use tests\codeception\api\FunctionalTester;
class ChangeUsernameCest { class ChangeUsernameCest {

View File

@ -1,9 +1,9 @@
<?php <?php
namespace tests\codeception\api\functional\accounts; namespace api\tests\functional\accounts;
use api\tests\_pages\AccountsRoute;
use api\tests\FunctionalTester;
use OTPHP\TOTP; use OTPHP\TOTP;
use tests\codeception\api\_pages\AccountsRoute;
use tests\codeception\api\FunctionalTester;
class DisableTwoFactorAuthCest { class DisableTwoFactorAuthCest {

View File

@ -1,9 +1,9 @@
<?php <?php
namespace tests\codeception\api\functional\accounts; namespace api\tests\functional\accounts;
use api\tests\_pages\AccountsRoute;
use api\tests\FunctionalTester;
use OTPHP\TOTP; use OTPHP\TOTP;
use tests\codeception\api\_pages\AccountsRoute;
use tests\codeception\api\FunctionalTester;
class EnableTwoFactorAuthCest { class EnableTwoFactorAuthCest {

View File

@ -1,8 +1,8 @@
<?php <?php
namespace tests\codeception\api\functional\accounts; namespace api\tests\functional\accounts;
use tests\codeception\api\_pages\AccountsRoute; use api\tests\_pages\AccountsRoute;
use tests\codeception\api\FunctionalTester; use api\tests\FunctionalTester;
class GetCest { class GetCest {
@ -36,6 +36,28 @@ class GetCest {
$I->canSeeResponseJsonMatchesJsonPath('$.passwordChangedAt'); $I->canSeeResponseJsonMatchesJsonPath('$.passwordChangedAt');
} }
public function testGetInfoAboutCurrentUser(FunctionalTester $I) {
$I->wantTo('get info about user with 0 id, e.g. current');
$I->amAuthenticated();
$this->route->get(0);
$I->canSeeResponseCodeIs(200);
$I->canSeeResponseIsJson();
$I->canSeeResponseContainsJson([
'id' => 1,
'uuid' => 'df936908-b2e1-544d-96f8-2977ec213022',
'username' => 'Admin',
'isOtpEnabled' => false,
'email' => 'admin@ely.by',
'lang' => 'en',
'isActive' => true,
'hasMojangUsernameCollision' => false,
'shouldAcceptRules' => false,
'elyProfileLink' => 'http://ely.by/u1',
]);
$I->canSeeResponseJsonMatchesJsonPath('$.passwordChangedAt');
}
public function testGetWithNotAcceptedLatestRules(FunctionalTester $I) { public function testGetWithNotAcceptedLatestRules(FunctionalTester $I) {
$accountId = $I->amAuthenticated('Veleyaba'); $accountId = $I->amAuthenticated('Veleyaba');

View File

@ -1,10 +1,10 @@
<?php <?php
namespace tests\codeception\api\functional\accounts; namespace api\tests\functional\accounts;
use api\tests\_pages\AccountsRoute;
use api\tests\functional\_steps\OauthSteps;
use api\tests\FunctionalTester;
use common\rbac\Permissions as P; use common\rbac\Permissions as P;
use tests\codeception\api\_pages\AccountsRoute;
use tests\codeception\api\functional\_steps\OauthSteps;
use tests\codeception\api\FunctionalTester;
class PardonCest { class PardonCest {

View File

@ -1,8 +1,8 @@
<?php <?php
namespace tests\codeception\api\functional\accounts; namespace api\tests\functional\accounts;
use tests\codeception\api\_pages\AccountsRoute; use api\tests\_pages\AccountsRoute;
use tests\codeception\api\FunctionalTester; use api\tests\FunctionalTester;
class TwoFactorAuthCredentialsCest { class TwoFactorAuthCredentialsCest {

View File

@ -1,9 +1,9 @@
<?php <?php
namespace tests\codeception\api\functional\authserver; namespace api\tests\functional\authserver;
use api\tests\_pages\AuthserverRoute;
use api\tests\FunctionalTester;
use Ramsey\Uuid\Uuid; use Ramsey\Uuid\Uuid;
use tests\codeception\api\_pages\AuthserverRoute;
use tests\codeception\api\FunctionalTester;
class AuthorizationCest { class AuthorizationCest {

View File

@ -1,9 +1,9 @@
<?php <?php
namespace tests\codeception\api\functional\authserver; namespace api\tests\functional\authserver;
use api\tests\_pages\AuthserverRoute;
use api\tests\functional\_steps\AuthserverSteps;
use Ramsey\Uuid\Uuid; use Ramsey\Uuid\Uuid;
use tests\codeception\api\_pages\AuthserverRoute;
use tests\codeception\api\functional\_steps\AuthserverSteps;
class InvalidateCest { class InvalidateCest {

View File

@ -1,9 +1,9 @@
<?php <?php
namespace tests\codeception\api\functional\authserver; namespace api\tests\functional\authserver;
use api\tests\_pages\AuthserverRoute;
use api\tests\functional\_steps\AuthserverSteps;
use Ramsey\Uuid\Uuid; use Ramsey\Uuid\Uuid;
use tests\codeception\api\_pages\AuthserverRoute;
use tests\codeception\api\functional\_steps\AuthserverSteps;
class RefreshCest { class RefreshCest {

View File

@ -1,8 +1,8 @@
<?php <?php
namespace tests\codeception\api\functional\authserver; namespace api\tests\functional\authserver;
use tests\codeception\api\_pages\AuthserverRoute; use api\tests\_pages\AuthserverRoute;
use tests\codeception\api\functional\_steps\AuthserverSteps; use api\tests\functional\_steps\AuthserverSteps;
class SignoutCest { class SignoutCest {

View File

@ -1,9 +1,9 @@
<?php <?php
namespace tests\codeception\api\functional\authserver; namespace api\tests\functional\authserver;
use api\tests\_pages\AuthserverRoute;
use api\tests\functional\_steps\AuthserverSteps;
use Ramsey\Uuid\Uuid; use Ramsey\Uuid\Uuid;
use tests\codeception\api\_pages\AuthserverRoute;
use tests\codeception\api\functional\_steps\AuthserverSteps;
class ValidateCest { class ValidateCest {

View File

@ -1,9 +1,9 @@
<?php <?php
namespace tests\codeception\api\functional\internal; namespace api\tests\functional\internal;
use tests\codeception\api\_pages\InternalRoute; use api\tests\_pages\InternalRoute;
use tests\codeception\api\functional\_steps\OauthSteps; use api\tests\functional\_steps\OauthSteps;
use tests\codeception\api\FunctionalTester; use api\tests\FunctionalTester;
class InfoCest { class InfoCest {

View File

@ -1,8 +1,8 @@
<?php <?php
namespace tests\codeception\api\functional\authserver; namespace api\tests\functional\authserver;
use tests\codeception\api\_pages\MojangApiRoute; use api\tests\_pages\MojangApiRoute;
use tests\codeception\api\FunctionalTester; use api\tests\FunctionalTester;
class UsernameToUuidCest { class UsernameToUuidCest {

View File

@ -1,8 +1,8 @@
<?php <?php
namespace tests\codeception\api\functional\authserver; namespace api\tests\functional\authserver;
use tests\codeception\api\_pages\MojangApiRoute; use api\tests\_pages\MojangApiRoute;
use tests\codeception\api\FunctionalTester; use api\tests\FunctionalTester;
class UsernamesToUuidsCest { class UsernamesToUuidsCest {

View File

@ -1,9 +1,9 @@
<?php <?php
namespace tests\codeception\api\functional\authserver; namespace api\tests\functional\authserver;
use api\tests\_pages\MojangApiRoute;
use api\tests\FunctionalTester;
use Faker\Provider\Uuid; use Faker\Provider\Uuid;
use tests\codeception\api\_pages\MojangApiRoute;
use tests\codeception\api\FunctionalTester;
class UuidToUsernamesHistoryCest { class UuidToUsernamesHistoryCest {

View File

@ -1,9 +1,9 @@
<?php <?php
namespace tests\codeception\api\oauth; namespace api\tests\functional\oauth;
use tests\codeception\api\_pages\OauthRoute; use api\tests\_pages\OauthRoute;
use tests\codeception\api\functional\_steps\OauthSteps; use api\tests\functional\_steps\OauthSteps;
use tests\codeception\api\FunctionalTester; use api\tests\FunctionalTester;
class AccessTokenCest { class AccessTokenCest {
@ -67,6 +67,7 @@ class AccessTokenCest {
'token_type' => 'Bearer', 'token_type' => 'Bearer',
]); ]);
$I->canSeeResponseJsonMatchesJsonPath('$.access_token'); $I->canSeeResponseJsonMatchesJsonPath('$.access_token');
$I->cantSeeResponseJsonMatchesJsonPath('$.refresh_token');
$I->canSeeResponseJsonMatchesJsonPath('$.expires_in'); $I->canSeeResponseJsonMatchesJsonPath('$.expires_in');
} }

View File

@ -1,9 +1,9 @@
<?php <?php
namespace tests\codeception\api\oauth; namespace api\tests\functional\oauth;
use api\tests\_pages\OauthRoute;
use api\tests\FunctionalTester;
use common\rbac\Permissions as P; use common\rbac\Permissions as P;
use tests\codeception\api\_pages\OauthRoute;
use tests\codeception\api\FunctionalTester;
class AuthCodeCest { class AuthCodeCest {

View File

@ -1,9 +1,9 @@
<?php <?php
namespace tests\codeception\api\oauth; namespace api\tests\functional\oauth;
use tests\codeception\api\_pages\OauthRoute; use api\tests\_pages\OauthRoute;
use tests\codeception\api\functional\_steps\OauthSteps; use api\tests\functional\_steps\OauthSteps;
use tests\codeception\api\FunctionalTester; use api\tests\FunctionalTester;
class ClientCredentialsCest { class ClientCredentialsCest {

View File

@ -1,8 +1,8 @@
<?php <?php
namespace tests\codeception\api\oauth; namespace api\tests\functional\oauth;
use tests\codeception\api\_pages\OauthRoute; use api\tests\_pages\OauthRoute;
use tests\codeception\api\FunctionalTester; use api\tests\FunctionalTester;
class CreateClientCest { class CreateClientCest {
@ -88,4 +88,23 @@ class CreateClientCest {
$I->canSeeResponseJsonMatchesJsonPath('$.data.createdAt'); $I->canSeeResponseJsonMatchesJsonPath('$.data.createdAt');
} }
public function testCreateApplicationWithTheSameNameAsDeletedApp(FunctionalTester $I) {
$I->wantTo('create application with the same name as the recently deleted application');
$I->amAuthenticated('admin');
$this->route->createClient('application', [
'name' => 'Deleted OAuth Client',
'description' => '',
'redirectUri' => 'http://some-site.com/oauth/ely',
'websiteUrl' => 'http://some-site.com',
]);
$I->canSeeResponseCodeIs(200);
$I->canSeeResponseIsJson();
$I->canSeeResponseContainsJson([
'success' => true,
'data' => [
'clientId' => 'deleted-oauth-client1',
],
]);
}
} }

View File

@ -1,8 +1,8 @@
<?php <?php
namespace tests\codeception\api\oauth; namespace api\tests\functional\oauth;
use tests\codeception\api\_pages\OauthRoute; use api\tests\_pages\OauthRoute;
use tests\codeception\api\FunctionalTester; use api\tests\FunctionalTester;
class DeleteClientCest { class DeleteClientCest {

View File

@ -1,8 +1,8 @@
<?php <?php
namespace tests\codeception\api\oauth; namespace api\tests\functional\oauth;
use tests\codeception\api\_pages\OauthRoute; use api\tests\_pages\OauthRoute;
use tests\codeception\api\FunctionalTester; use api\tests\FunctionalTester;
class GetClientsCest { class GetClientsCest {

View File

@ -1,9 +1,9 @@
<?php <?php
namespace codeception\api\functional; namespace api\tests\functional\oauth;
use tests\codeception\api\_pages\IdentityInfoRoute; use api\tests\_pages\IdentityInfoRoute;
use tests\codeception\api\functional\_steps\OauthSteps; use api\tests\functional\_steps\OauthSteps;
use tests\codeception\api\FunctionalTester; use api\tests\FunctionalTester;
class IdentityInfoCest { class IdentityInfoCest {
@ -16,7 +16,20 @@ class IdentityInfoCest {
$this->route = new IdentityInfoRoute($I); $this->route = new IdentityInfoRoute($I);
} }
public function testGetErrorIfNoAccessToken(OauthSteps $I) {
$I->wantToTest('behavior when this endpoint called without Authorization header');
$this->route->info();
$I->canSeeResponseCodeIs(401);
$I->canSeeResponseIsJson();
$I->canSeeResponseContainsJson([
'name' => 'Unauthorized',
'status' => 401,
'message' => 'Your request was made with invalid credentials.',
]);
}
public function testGetErrorIfNotEnoughPerms(OauthSteps $I) { public function testGetErrorIfNotEnoughPerms(OauthSteps $I) {
$I->wantToTest('behavior when this endpoint called with token, that have not enough scopes');
$accessToken = $I->getAccessToken(); $accessToken = $I->getAccessToken();
$I->amBearerAuthenticated($accessToken); $I->amBearerAuthenticated($accessToken);
$this->route->info(); $this->route->info();
@ -25,6 +38,7 @@ class IdentityInfoCest {
$I->canSeeResponseContainsJson([ $I->canSeeResponseContainsJson([
'name' => 'Forbidden', 'name' => 'Forbidden',
'status' => 403, 'status' => 403,
'message' => 'You are not allowed to perform this action.',
]); ]);
} }

View File

@ -1,11 +1,11 @@
<?php <?php
namespace tests\codeception\api\oauth; namespace api\tests\functional\oauth;
use api\components\OAuth2\Storage\ScopeStorage as S; use api\components\OAuth2\Storage\ScopeStorage as S;
use api\tests\_pages\OauthRoute;
use api\tests\functional\_steps\OauthSteps;
use api\tests\FunctionalTester;
use common\rbac\Permissions as P; use common\rbac\Permissions as P;
use tests\codeception\api\_pages\OauthRoute;
use tests\codeception\api\functional\_steps\OauthSteps;
use tests\codeception\api\FunctionalTester;
class RefreshTokenCest { class RefreshTokenCest {

View File

@ -1,8 +1,8 @@
<?php <?php
namespace tests\codeception\api\oauth; namespace api\tests\functional\oauth;
use tests\codeception\api\_pages\OauthRoute; use api\tests\_pages\OauthRoute;
use tests\codeception\api\FunctionalTester; use api\tests\FunctionalTester;
class ResetClientCest { class ResetClientCest {

View File

@ -1,8 +1,8 @@
<?php <?php
namespace tests\codeception\api\oauth; namespace api\tests\functional\oauth;
use tests\codeception\api\_pages\OauthRoute; use api\tests\_pages\OauthRoute;
use tests\codeception\api\FunctionalTester; use api\tests\FunctionalTester;
class UpdateClientCest { class UpdateClientCest {

View File

@ -1,10 +1,10 @@
<?php <?php
namespace tests\codeception\api\functional\sessionserver; namespace api\tests\functional\sessionserver;
use api\tests\_pages\SessionServerRoute;
use api\tests\functional\_steps\SessionServerSteps;
use api\tests\FunctionalTester;
use Faker\Provider\Uuid; use Faker\Provider\Uuid;
use tests\codeception\api\_pages\SessionServerRoute;
use tests\codeception\api\functional\_steps\SessionServerSteps;
use tests\codeception\api\FunctionalTester;
class HasJoinedCest { class HasJoinedCest {
@ -19,7 +19,7 @@ class HasJoinedCest {
public function hasJoined(SessionServerSteps $I) { public function hasJoined(SessionServerSteps $I) {
$I->wantTo('check hasJoined user to some server'); $I->wantTo('check hasJoined user to some server');
list($username, $serverId) = $I->amJoined(); [$username, $serverId] = $I->amJoined();
$this->route->hasJoined([ $this->route->hasJoined([
'username' => $username, 'username' => $username,

View File

@ -1,10 +1,10 @@
<?php <?php
namespace tests\codeception\api\functional\sessionserver; namespace api\tests\functional\sessionserver;
use api\tests\_pages\SessionServerRoute;
use api\tests\functional\_steps\SessionServerSteps;
use api\tests\FunctionalTester;
use Faker\Provider\Uuid; use Faker\Provider\Uuid;
use tests\codeception\api\_pages\SessionServerRoute;
use tests\codeception\api\functional\_steps\SessionServerSteps;
use tests\codeception\api\FunctionalTester;
class HasJoinedLegacyCest { class HasJoinedLegacyCest {
@ -19,7 +19,7 @@ class HasJoinedLegacyCest {
public function hasJoined(SessionServerSteps $I) { public function hasJoined(SessionServerSteps $I) {
$I->wantTo('test hasJoined user to some server by legacy version'); $I->wantTo('test hasJoined user to some server by legacy version');
list($username, $serverId) = $I->amJoined(true); [$username, $serverId] = $I->amJoined(true);
$this->route->hasJoinedLegacy([ $this->route->hasJoinedLegacy([
'user' => $username, 'user' => $username,

View File

@ -1,12 +1,12 @@
<?php <?php
namespace tests\codeception\api\functional\sessionserver; namespace api\tests\functional\sessionserver;
use api\tests\_pages\SessionServerRoute;
use api\tests\functional\_steps\AuthserverSteps;
use api\tests\functional\_steps\OauthSteps;
use api\tests\FunctionalTester;
use common\rbac\Permissions as P; use common\rbac\Permissions as P;
use Faker\Provider\Uuid; use Faker\Provider\Uuid;
use tests\codeception\api\_pages\SessionServerRoute;
use tests\codeception\api\functional\_steps\AuthserverSteps;
use tests\codeception\api\functional\_steps\OauthSteps;
use tests\codeception\api\FunctionalTester;
class JoinCest { class JoinCest {

View File

@ -1,12 +1,12 @@
<?php <?php
namespace tests\codeception\api\functional\sessionserver; namespace api\tests\functional\sessionserver;
use api\tests\_pages\SessionServerRoute;
use api\tests\functional\_steps\AuthserverSteps;
use api\tests\functional\_steps\OauthSteps;
use api\tests\FunctionalTester;
use common\rbac\Permissions as P; use common\rbac\Permissions as P;
use Faker\Provider\Uuid; use Faker\Provider\Uuid;
use tests\codeception\api\_pages\SessionServerRoute;
use tests\codeception\api\functional\_steps\AuthserverSteps;
use tests\codeception\api\functional\_steps\OauthSteps;
use tests\codeception\api\FunctionalTester;
class JoinLegacyCest { class JoinLegacyCest {

View File

@ -1,10 +1,10 @@
<?php <?php
namespace tests\codeception\api\functional\sessionserver; namespace api\tests\functional\sessionserver;
use api\tests\_pages\SessionServerRoute;
use api\tests\functional\_steps\SessionServerSteps;
use api\tests\FunctionalTester;
use Faker\Provider\Uuid; use Faker\Provider\Uuid;
use tests\codeception\api\_pages\SessionServerRoute;
use tests\codeception\api\functional\_steps\SessionServerSteps;
use tests\codeception\api\FunctionalTester;
class ProfileCest { class ProfileCest {

View File

@ -0,0 +1,10 @@
suite_namespace: api\tests\unit
actor: UnitTester
modules:
enabled:
- Asserts
- Yii2:
part: [orm, email, fixtures]
configFile: tests/config/unit.php
- common\tests\_support\queue\CodeceptionQueueHelper
- common\tests\_support\Mockery

View File

@ -1,12 +1,12 @@
<?php <?php
namespace tests\codeception\api\unit; namespace api\tests\unit;
use Mockery; use Mockery;
class TestCase extends \Codeception\Test\Unit { class TestCase extends \Codeception\Test\Unit {
/** /**
* @var \tests\codeception\api\UnitTester * @var \api\tests\UnitTester
*/ */
protected $tester; protected $tester;

View File

@ -2,19 +2,19 @@
namespace codeception\api\unit\components\ReCaptcha; namespace codeception\api\unit\components\ReCaptcha;
use api\components\ReCaptcha\Validator; use api\components\ReCaptcha\Validator;
use api\tests\unit\TestCase;
use GuzzleHttp\ClientInterface; use GuzzleHttp\ClientInterface;
use GuzzleHttp\Exception\ConnectException; use GuzzleHttp\Exception\ConnectException;
use GuzzleHttp\Psr7\Response; use GuzzleHttp\Psr7\Response;
use phpmock\mockery\PHPMockery; use phpmock\mockery\PHPMockery;
use ReflectionClass; use ReflectionClass;
use tests\codeception\api\unit\TestCase;
class ValidatorTest extends TestCase { class ValidatorTest extends TestCase {
public function testValidateEmptyValue() { public function testValidateEmptyValue() {
$validator = new Validator(mock(ClientInterface::class)); $validator = new Validator(mock(ClientInterface::class));
$this->assertFalse($validator->validate('', $error)); $this->assertFalse($validator->validate('', $error));
$this->assertEquals('error.captcha_required', $error, 'Get error.captcha_required, if passed empty value'); $this->assertSame('error.captcha_required', $error, 'Get error.captcha_required, if passed empty value');
} }
public function testValidateInvalidValue() { public function testValidateInvalidValue() {
@ -28,7 +28,7 @@ class ValidatorTest extends TestCase {
$validator = new Validator($mockClient); $validator = new Validator($mockClient);
$this->assertFalse($validator->validate('12341234', $error)); $this->assertFalse($validator->validate('12341234', $error));
$this->assertEquals('error.captcha_invalid', $error, 'Get error.captcha_invalid, if passed wrong value'); $this->assertSame('error.captcha_invalid', $error, 'Get error.captcha_invalid, if passed wrong value');
} }
public function testValidateWithNetworkTroubles() { public function testValidateWithNetworkTroubles() {

View File

@ -4,16 +4,16 @@ namespace codeception\api\unit\components\User;
use api\components\User\AuthenticationResult; use api\components\User\AuthenticationResult;
use api\components\User\Component; use api\components\User\Component;
use api\components\User\Identity; use api\components\User\Identity;
use api\tests\unit\TestCase;
use common\models\Account; use common\models\Account;
use common\models\AccountSession; use common\models\AccountSession;
use common\tests\_support\ProtectedCaller;
use common\tests\fixtures\AccountFixture;
use common\tests\fixtures\AccountSessionFixture;
use common\tests\fixtures\MinecraftAccessKeyFixture;
use Emarref\Jwt\Claim; use Emarref\Jwt\Claim;
use Emarref\Jwt\Jwt; use Emarref\Jwt\Jwt;
use Emarref\Jwt\Token; use Emarref\Jwt\Token;
use tests\codeception\api\unit\TestCase;
use tests\codeception\common\_support\ProtectedCaller;
use tests\codeception\common\fixtures\AccountFixture;
use tests\codeception\common\fixtures\AccountSessionFixture;
use tests\codeception\common\fixtures\MinecraftAccessKeyFixture;
use Yii; use Yii;
use yii\web\Request; use yii\web\Request;
@ -45,17 +45,17 @@ class ComponentTest extends TestCase {
$result = $this->component->createJwtAuthenticationToken($account, false); $result = $this->component->createJwtAuthenticationToken($account, false);
$this->assertInstanceOf(AuthenticationResult::class, $result); $this->assertInstanceOf(AuthenticationResult::class, $result);
$this->assertNull($result->getSession()); $this->assertNull($result->getSession());
$this->assertEquals($account, $result->getAccount()); $this->assertSame($account, $result->getAccount());
$payloads = (new Jwt())->deserialize($result->getJwt())->getPayload(); $payloads = (new Jwt())->deserialize($result->getJwt())->getPayload();
/** @noinspection NullPointerExceptionInspection */ /** @noinspection NullPointerExceptionInspection */
$this->assertEquals(time(), $payloads->findClaimByName(Claim\IssuedAt::NAME)->getValue(), '', 3); $this->assertEqualsWithDelta(time(), $payloads->findClaimByName(Claim\IssuedAt::NAME)->getValue(), 3);
/** @noinspection SummerTimeUnsafeTimeManipulationInspection */ /** @noinspection SummerTimeUnsafeTimeManipulationInspection */
/** @noinspection NullPointerExceptionInspection */ /** @noinspection NullPointerExceptionInspection */
$this->assertEquals(time() + 60 * 60 * 24 * 7, $payloads->findClaimByName('exp')->getValue(), '', 3); $this->assertEqualsWithDelta(time() + 60 * 60 * 24 * 7, $payloads->findClaimByName('exp')->getValue(), 3);
/** @noinspection NullPointerExceptionInspection */ /** @noinspection NullPointerExceptionInspection */
$this->assertEquals('ely|1', $payloads->findClaimByName('sub')->getValue()); $this->assertSame('ely|1', $payloads->findClaimByName('sub')->getValue());
/** @noinspection NullPointerExceptionInspection */ /** @noinspection NullPointerExceptionInspection */
$this->assertEquals('accounts_web_user', $payloads->findClaimByName('ely-scopes')->getValue()); $this->assertSame('accounts_web_user', $payloads->findClaimByName('ely-scopes')->getValue());
$this->assertNull($payloads->findClaimByName('jti')); $this->assertNull($payloads->findClaimByName('jti'));
/** @var Account $account */ /** @var Account $account */
@ -63,20 +63,20 @@ class ComponentTest extends TestCase {
$result = $this->component->createJwtAuthenticationToken($account, true); $result = $this->component->createJwtAuthenticationToken($account, true);
$this->assertInstanceOf(AuthenticationResult::class, $result); $this->assertInstanceOf(AuthenticationResult::class, $result);
$this->assertInstanceOf(AccountSession::class, $result->getSession()); $this->assertInstanceOf(AccountSession::class, $result->getSession());
$this->assertEquals($account, $result->getAccount()); $this->assertSame($account, $result->getAccount());
/** @noinspection NullPointerExceptionInspection */ /** @noinspection NullPointerExceptionInspection */
$this->assertTrue($result->getSession()->refresh()); $this->assertTrue($result->getSession()->refresh());
$payloads = (new Jwt())->deserialize($result->getJwt())->getPayload(); $payloads = (new Jwt())->deserialize($result->getJwt())->getPayload();
/** @noinspection NullPointerExceptionInspection */ /** @noinspection NullPointerExceptionInspection */
$this->assertEquals(time(), $payloads->findClaimByName(Claim\IssuedAt::NAME)->getValue(), '', 3); $this->assertEqualsWithDelta(time(), $payloads->findClaimByName(Claim\IssuedAt::NAME)->getValue(), 3);
/** @noinspection NullPointerExceptionInspection */ /** @noinspection NullPointerExceptionInspection */
$this->assertEquals(time() + 3600, $payloads->findClaimByName('exp')->getValue(), '', 3); $this->assertEqualsWithDelta(time() + 3600, $payloads->findClaimByName('exp')->getValue(), 3);
/** @noinspection NullPointerExceptionInspection */ /** @noinspection NullPointerExceptionInspection */
$this->assertEquals('ely|1', $payloads->findClaimByName('sub')->getValue()); $this->assertSame('ely|1', $payloads->findClaimByName('sub')->getValue());
/** @noinspection NullPointerExceptionInspection */ /** @noinspection NullPointerExceptionInspection */
$this->assertEquals('accounts_web_user', $payloads->findClaimByName('ely-scopes')->getValue()); $this->assertSame('accounts_web_user', $payloads->findClaimByName('ely-scopes')->getValue());
/** @noinspection NullPointerExceptionInspection */ /** @noinspection NullPointerExceptionInspection */
$this->assertEquals($result->getSession()->id, $payloads->findClaimByName('jti')->getValue()); $this->assertSame($result->getSession()->id, $payloads->findClaimByName('jti')->getValue());
} }
public function testRenewJwtAuthenticationToken() { public function testRenewJwtAuthenticationToken() {
@ -85,23 +85,22 @@ class ComponentTest extends TestCase {
/** @var AccountSession $session */ /** @var AccountSession $session */
$session = $this->tester->grabFixture('sessions', 'admin'); $session = $this->tester->grabFixture('sessions', 'admin');
$result = $this->component->renewJwtAuthenticationToken($session); $result = $this->component->renewJwtAuthenticationToken($session);
$this->assertInstanceOf(AuthenticationResult::class, $result); $this->assertSame($session, $result->getSession());
$this->assertEquals($session, $result->getSession()); $this->assertSame($session->account_id, $result->getAccount()->id);
$this->assertEquals($session->account_id, $result->getAccount()->id);
$session->refresh(); // reload data from db $session->refresh(); // reload data from db
$this->assertEquals(time(), $session->last_refreshed_at, '', 3); $this->assertEqualsWithDelta(time(), $session->last_refreshed_at, 3);
$this->assertEquals($userIP, $session->getReadableIp()); $this->assertSame($userIP, $session->getReadableIp());
$payloads = (new Jwt())->deserialize($result->getJwt())->getPayload(); $payloads = (new Jwt())->deserialize($result->getJwt())->getPayload();
/** @noinspection NullPointerExceptionInspection */ /** @noinspection NullPointerExceptionInspection */
$this->assertEquals(time(), $payloads->findClaimByName(Claim\IssuedAt::NAME)->getValue(), '', 3); $this->assertEqualsWithDelta(time(), $payloads->findClaimByName(Claim\IssuedAt::NAME)->getValue(), 3);
/** @noinspection NullPointerExceptionInspection */ /** @noinspection NullPointerExceptionInspection */
$this->assertEquals(time() + 3600, $payloads->findClaimByName('exp')->getValue(), '', 3); $this->assertEqualsWithDelta(time() + 3600, $payloads->findClaimByName('exp')->getValue(), 3);
/** @noinspection NullPointerExceptionInspection */ /** @noinspection NullPointerExceptionInspection */
$this->assertEquals('ely|1', $payloads->findClaimByName('sub')->getValue()); $this->assertSame('ely|1', $payloads->findClaimByName('sub')->getValue());
/** @noinspection NullPointerExceptionInspection */ /** @noinspection NullPointerExceptionInspection */
$this->assertEquals('accounts_web_user', $payloads->findClaimByName('ely-scopes')->getValue()); $this->assertSame('accounts_web_user', $payloads->findClaimByName('ely-scopes')->getValue());
/** @noinspection NullPointerExceptionInspection */ /** @noinspection NullPointerExceptionInspection */
$this->assertEquals($session->id, $payloads->findClaimByName('jti')->getValue(), 'session has not changed'); $this->assertSame($session->id, $payloads->findClaimByName('jti')->getValue(), 'session has not changed');
} }
public function testParseToken() { public function testParseToken() {
@ -123,7 +122,6 @@ class ComponentTest extends TestCase {
->getMock(); ->getMock();
$component $component
->expects($this->any())
->method('getIsGuest') ->method('getIsGuest')
->willReturn(false); ->willReturn(false);
@ -132,7 +130,7 @@ class ComponentTest extends TestCase {
$session = $component->getActiveSession(); $session = $component->getActiveSession();
$this->assertInstanceOf(AccountSession::class, $session); $this->assertInstanceOf(AccountSession::class, $session);
/** @noinspection NullPointerExceptionInspection */ /** @noinspection NullPointerExceptionInspection */
$this->assertEquals($session->id, $result->getSession()->id); $this->assertSame($session->id, $result->getSession()->id);
} }
public function testTerminateSessions() { public function testTerminateSessions() {
@ -157,8 +155,8 @@ class ComponentTest extends TestCase {
$component->terminateSessions($account, Component::KEEP_CURRENT_SESSION); $component->terminateSessions($account, Component::KEEP_CURRENT_SESSION);
$sessions = $account->getSessions()->all(); $sessions = $account->getSessions()->all();
$this->assertEquals(1, count($sessions)); $this->assertCount(1, $sessions);
$this->assertTrue($sessions[0]->id === $session->id); $this->assertSame($session->id, $sessions[0]->id);
$component->terminateSessions($account); $component->terminateSessions($account);
$this->assertEmpty($account->getSessions()->all()); $this->assertEmpty($account->getSessions()->all());

View File

@ -1,7 +1,8 @@
<?php <?php
namespace tests\codeception\api\unit\components\User; namespace api\tests\unit\components\User;
use api\components\User\AuthenticationResult; use api\components\User\AuthenticationResult;
use api\tests\unit\TestCase;
use common\models\Account; use common\models\Account;
use common\models\AccountSession; use common\models\AccountSession;
use Emarref\Jwt\Algorithm\Hs256; use Emarref\Jwt\Algorithm\Hs256;
@ -9,7 +10,6 @@ use Emarref\Jwt\Claim\Expiration;
use Emarref\Jwt\Encryption\Factory as EncryptionFactory; use Emarref\Jwt\Encryption\Factory as EncryptionFactory;
use Emarref\Jwt\Jwt; use Emarref\Jwt\Jwt;
use Emarref\Jwt\Token; use Emarref\Jwt\Token;
use tests\codeception\api\unit\TestCase;
class JwtAuthenticationResultTest extends TestCase { class JwtAuthenticationResultTest extends TestCase {
@ -17,12 +17,12 @@ class JwtAuthenticationResultTest extends TestCase {
$account = new Account(); $account = new Account();
$account->id = 123; $account->id = 123;
$model = new AuthenticationResult($account, '', null); $model = new AuthenticationResult($account, '', null);
$this->assertEquals($account, $model->getAccount()); $this->assertSame($account, $model->getAccount());
} }
public function testGetJwt() { public function testGetJwt() {
$model = new AuthenticationResult(new Account(), 'mocked jwt', null); $model = new AuthenticationResult(new Account(), 'mocked jwt', null);
$this->assertEquals('mocked jwt', $model->getJwt()); $this->assertSame('mocked jwt', $model->getJwt());
} }
public function testGetSession() { public function testGetSession() {
@ -32,14 +32,14 @@ class JwtAuthenticationResultTest extends TestCase {
$session = new AccountSession(); $session = new AccountSession();
$session->id = 321; $session->id = 321;
$model = new AuthenticationResult(new Account(), '', $session); $model = new AuthenticationResult(new Account(), '', $session);
$this->assertEquals($session, $model->getSession()); $this->assertSame($session, $model->getSession());
} }
public function testGetAsResponse() { public function testGetAsResponse() {
$jwtToken = $this->createJwtToken(time() + 3600); $jwtToken = $this->createJwtToken(time() + 3600);
$model = new AuthenticationResult(new Account(), $jwtToken, null); $model = new AuthenticationResult(new Account(), $jwtToken, null);
$result = $model->getAsResponse(); $result = $model->getAsResponse();
$this->assertEquals($jwtToken, $result['access_token']); $this->assertSame($jwtToken, $result['access_token']);
$this->assertSame(3600, $result['expires_in']); $this->assertSame(3600, $result['expires_in']);
/** @noinspection SummerTimeUnsafeTimeManipulationInspection */ /** @noinspection SummerTimeUnsafeTimeManipulationInspection */
@ -48,8 +48,8 @@ class JwtAuthenticationResultTest extends TestCase {
$session->refresh_token = 'refresh token'; $session->refresh_token = 'refresh token';
$model = new AuthenticationResult(new Account(), $jwtToken, $session); $model = new AuthenticationResult(new Account(), $jwtToken, $session);
$result = $model->getAsResponse(); $result = $model->getAsResponse();
$this->assertEquals($jwtToken, $result['access_token']); $this->assertSame($jwtToken, $result['access_token']);
$this->assertEquals('refresh token', $result['refresh_token']); $this->assertSame('refresh token', $result['refresh_token']);
$this->assertSame(86400, $result['expires_in']); $this->assertSame(86400, $result['expires_in']);
} }

View File

@ -1,8 +1,8 @@
<?php <?php
namespace tests\codeception\api\unit\filters; namespace api\tests\unit\filters;
use api\filters\NginxCache; use api\filters\NginxCache;
use tests\codeception\api\unit\TestCase; use api\tests\unit\TestCase;
use Yii; use Yii;
use yii\base\Action; use yii\base\Action;
use yii\web\Controller; use yii\web\Controller;

View File

@ -2,8 +2,8 @@
namespace codeception\api\unit\models; namespace codeception\api\unit\models;
use api\models\FeedbackForm; use api\models\FeedbackForm;
use api\tests\unit\TestCase;
use common\models\Account; use common\models\Account;
use tests\codeception\api\unit\TestCase;
use yii\swiftmailer\Message; use yii\swiftmailer\Message;
class FeedbackFormTest extends TestCase { class FeedbackFormTest extends TestCase {

View File

@ -4,13 +4,13 @@ namespace codeception\api\unit\models;
use api\components\User\IdentityInterface; use api\components\User\IdentityInterface;
use api\components\User\Jwt; use api\components\User\Jwt;
use api\components\User\JwtIdentity; use api\components\User\JwtIdentity;
use api\tests\unit\TestCase;
use Codeception\Specify; use Codeception\Specify;
use common\tests\_support\ProtectedCaller;
use common\tests\fixtures\AccountFixture;
use Emarref\Jwt\Claim; use Emarref\Jwt\Claim;
use Emarref\Jwt\Encryption\Factory as EncryptionFactory; use Emarref\Jwt\Encryption\Factory as EncryptionFactory;
use Emarref\Jwt\Token; use Emarref\Jwt\Token;
use tests\codeception\api\unit\TestCase;
use tests\codeception\common\_support\ProtectedCaller;
use tests\codeception\common\fixtures\AccountFixture;
use Yii; use Yii;
class JwtIdentityTest extends TestCase { class JwtIdentityTest extends TestCase {
@ -27,8 +27,8 @@ class JwtIdentityTest extends TestCase {
$token = $this->generateToken(); $token = $this->generateToken();
$identity = JwtIdentity::findIdentityByAccessToken($token); $identity = JwtIdentity::findIdentityByAccessToken($token);
$this->assertInstanceOf(IdentityInterface::class, $identity); $this->assertInstanceOf(IdentityInterface::class, $identity);
$this->assertEquals($token, $identity->getId()); $this->assertSame($token, $identity->getId());
$this->assertEquals($this->tester->grabFixture('accounts', 'admin')['id'], $identity->getAccount()->id); $this->assertSame($this->tester->grabFixture('accounts', 'admin')['id'], $identity->getAccount()->id);
} }
/** /**

View File

@ -1,13 +1,13 @@
<?php <?php
namespace tests\codeception\api\models\authentication; namespace api\tests\_support\models\authentication;
use api\components\User\AuthenticationResult; use api\components\User\AuthenticationResult;
use api\models\authentication\ConfirmEmailForm; use api\models\authentication\ConfirmEmailForm;
use api\tests\unit\TestCase;
use common\models\Account; use common\models\Account;
use common\models\AccountSession; use common\models\AccountSession;
use common\models\EmailActivation; use common\models\EmailActivation;
use tests\codeception\api\unit\TestCase; use common\tests\fixtures\EmailActivationFixture;
use tests\codeception\common\fixtures\EmailActivationFixture;
class ConfirmEmailFormTest extends TestCase { class ConfirmEmailFormTest extends TestCase {
@ -27,7 +27,7 @@ class ConfirmEmailFormTest extends TestCase {
$this->assertFalse($activationExists, 'email activation key is not exist'); $this->assertFalse($activationExists, 'email activation key is not exist');
/** @var Account $account */ /** @var Account $account */
$account = Account::findOne($fixture['account_id']); $account = Account::findOne($fixture['account_id']);
$this->assertEquals(Account::STATUS_ACTIVE, $account->status, 'user status changed to active'); $this->assertSame(Account::STATUS_ACTIVE, $account->status, 'user status changed to active');
} }
private function createModel($key) { private function createModel($key) {

View File

@ -3,20 +3,20 @@ namespace codeception\api\unit\models\authentication;
use api\components\ReCaptcha\Validator as ReCaptchaValidator; use api\components\ReCaptcha\Validator as ReCaptchaValidator;
use api\models\authentication\ForgotPasswordForm; use api\models\authentication\ForgotPasswordForm;
use api\tests\unit\TestCase;
use Codeception\Specify; use Codeception\Specify;
use common\models\Account; use common\models\Account;
use common\models\EmailActivation; use common\models\EmailActivation;
use common\tasks\SendPasswordRecoveryEmail; use common\tasks\SendPasswordRecoveryEmail;
use common\tests\fixtures\AccountFixture;
use common\tests\fixtures\EmailActivationFixture;
use GuzzleHttp\ClientInterface; use GuzzleHttp\ClientInterface;
use tests\codeception\api\unit\TestCase;
use tests\codeception\common\fixtures\AccountFixture;
use tests\codeception\common\fixtures\EmailActivationFixture;
use Yii; use Yii;
class ForgotPasswordFormTest extends TestCase { class ForgotPasswordFormTest extends TestCase {
use Specify; use Specify;
public function setUp() { protected function setUp() {
parent::setUp(); parent::setUp();
Yii::$container->set(ReCaptchaValidator::class, new class(mock(ClientInterface::class)) extends ReCaptchaValidator { Yii::$container->set(ReCaptchaValidator::class, new class(mock(ClientInterface::class)) extends ReCaptchaValidator {
public function validateValue($value) { public function validateValue($value) {
@ -35,7 +35,7 @@ class ForgotPasswordFormTest extends TestCase {
public function testValidateLogin() { public function testValidateLogin() {
$model = new ForgotPasswordForm(['login' => 'unexist']); $model = new ForgotPasswordForm(['login' => 'unexist']);
$model->validateLogin('login'); $model->validateLogin('login');
$this->assertEquals(['error.login_not_exist'], $model->getErrors('login'), 'error.login_not_exist if login is invalid'); $this->assertSame(['error.login_not_exist'], $model->getErrors('login'), 'error.login_not_exist if login is invalid');
$model = new ForgotPasswordForm(['login' => $this->tester->grabFixture('accounts', 'admin')['username']]); $model = new ForgotPasswordForm(['login' => $this->tester->grabFixture('accounts', 'admin')['username']]);
$model->validateLogin('login'); $model->validateLogin('login');
@ -47,7 +47,7 @@ class ForgotPasswordFormTest extends TestCase {
'login' => $this->tester->grabFixture('accounts', 'not-activated-account')['username'], 'login' => $this->tester->grabFixture('accounts', 'not-activated-account')['username'],
]); ]);
$model->validateActivity('login'); $model->validateActivity('login');
$this->assertEquals(['error.account_not_activated'], $model->getErrors('login'), 'expected error if account is not confirmed'); $this->assertSame(['error.account_not_activated'], $model->getErrors('login'), 'expected error if account is not confirmed');
$model = new ForgotPasswordForm([ $model = new ForgotPasswordForm([
'login' => $this->tester->grabFixture('accounts', 'admin')['username'], 'login' => $this->tester->grabFixture('accounts', 'admin')['username'],
@ -62,7 +62,7 @@ class ForgotPasswordFormTest extends TestCase {
'key' => $this->tester->grabFixture('emailActivations', 'freshPasswordRecovery')['key'], 'key' => $this->tester->grabFixture('emailActivations', 'freshPasswordRecovery')['key'],
]); ]);
$model->validateFrequency('login'); $model->validateFrequency('login');
$this->assertEquals(['error.recently_sent_message'], $model->getErrors('login'), 'error.account_not_activated if recently was message'); $this->assertSame(['error.recently_sent_message'], $model->getErrors('login'), 'error.account_not_activated if recently was message');
$model = $this->createModel([ $model = $this->createModel([
'login' => $this->tester->grabFixture('accounts', 'admin')['username'], 'login' => $this->tester->grabFixture('accounts', 'admin')['username'],

View File

@ -1,26 +1,26 @@
<?php <?php
namespace tests\codeception\api\models\authentication; namespace api\tests\_support\models\authentication;
use api\components\User\AuthenticationResult; use api\components\User\AuthenticationResult;
use api\models\authentication\LoginForm; use api\models\authentication\LoginForm;
use api\tests\unit\TestCase;
use Codeception\Specify; use Codeception\Specify;
use common\models\Account; use common\models\Account;
use common\tests\fixtures\AccountFixture;
use OTPHP\TOTP; use OTPHP\TOTP;
use tests\codeception\api\unit\TestCase;
use tests\codeception\common\fixtures\AccountFixture;
class LoginFormTest extends TestCase { class LoginFormTest extends TestCase {
use Specify; use Specify;
private $originalRemoteAddr; private $originalRemoteAddr;
public function setUp() { protected function setUp() {
$this->originalRemoteAddr = $_SERVER['REMOTE_ADDR'] ?? null; $this->originalRemoteAddr = $_SERVER['REMOTE_ADDR'] ?? null;
$_SERVER['REMOTE_ADDR'] = '127.0.0.1'; $_SERVER['REMOTE_ADDR'] = '127.0.0.1';
parent::setUp(); parent::setUp();
} }
public function tearDown() { protected function tearDown() {
parent::tearDown(); parent::tearDown();
$_SERVER['REMOTE_ADDR'] = $this->originalRemoteAddr; $_SERVER['REMOTE_ADDR'] = $this->originalRemoteAddr;
} }
@ -38,7 +38,7 @@ class LoginFormTest extends TestCase {
'account' => null, 'account' => null,
]); ]);
$model->validateLogin('login'); $model->validateLogin('login');
$this->assertEquals(['error.login_not_exist'], $model->getErrors('login')); $this->assertSame(['error.login_not_exist'], $model->getErrors('login'));
}); });
$this->specify('no errors if login exists', function() { $this->specify('no errors if login exists', function() {
@ -58,7 +58,7 @@ class LoginFormTest extends TestCase {
'account' => new Account(['password' => '12345678']), 'account' => new Account(['password' => '12345678']),
]); ]);
$model->validatePassword('password'); $model->validatePassword('password');
$this->assertEquals(['error.password_incorrect'], $model->getErrors('password')); $this->assertSame(['error.password_incorrect'], $model->getErrors('password'));
}); });
$this->specify('no errors if password valid', function() { $this->specify('no errors if password valid', function() {
@ -84,7 +84,7 @@ class LoginFormTest extends TestCase {
'account' => $account, 'account' => $account,
]); ]);
$model->validateTotp('totp'); $model->validateTotp('totp');
$this->assertEquals(['error.totp_incorrect'], $model->getErrors('totp')); $this->assertSame(['error.totp_incorrect'], $model->getErrors('totp'));
}); });
$totp = TOTP::create($account->otp_secret); $totp = TOTP::create($account->otp_secret);
@ -105,7 +105,7 @@ class LoginFormTest extends TestCase {
'account' => new Account(['status' => Account::STATUS_REGISTERED]), 'account' => new Account(['status' => Account::STATUS_REGISTERED]),
]); ]);
$model->validateActivity('login'); $model->validateActivity('login');
$this->assertEquals(['error.account_not_activated'], $model->getErrors('login')); $this->assertSame(['error.account_not_activated'], $model->getErrors('login'));
}); });
$this->specify('error.account_banned if account has banned status', function() { $this->specify('error.account_banned if account has banned status', function() {
@ -113,7 +113,7 @@ class LoginFormTest extends TestCase {
'account' => new Account(['status' => Account::STATUS_BANNED]), 'account' => new Account(['status' => Account::STATUS_BANNED]),
]); ]);
$model->validateActivity('login'); $model->validateActivity('login');
$this->assertEquals(['error.account_banned'], $model->getErrors('login')); $this->assertSame(['error.account_banned'], $model->getErrors('login'));
}); });
$this->specify('no errors if account active', function() { $this->specify('no errors if account active', function() {
@ -146,7 +146,7 @@ class LoginFormTest extends TestCase {
]); ]);
$this->assertInstanceOf(AuthenticationResult::class, $model->login()); $this->assertInstanceOf(AuthenticationResult::class, $model->login());
$this->assertEmpty($model->getErrors()); $this->assertEmpty($model->getErrors());
$this->assertEquals( $this->assertSame(
Account::PASS_HASH_STRATEGY_YII2, Account::PASS_HASH_STRATEGY_YII2,
$model->getAccount()->password_hash_strategy, $model->getAccount()->password_hash_strategy,
'user, that login using account with old pass hash strategy should update it automatically' 'user, that login using account with old pass hash strategy should update it automatically'

View File

@ -1,12 +1,12 @@
<?php <?php
namespace tests\codeception\api\models\authentication; namespace api\tests\_support\models\authentication;
use api\components\User\Component; use api\components\User\Component;
use api\components\User\Identity; use api\components\User\Identity;
use api\models\authentication\LogoutForm; use api\models\authentication\LogoutForm;
use api\tests\unit\TestCase;
use Codeception\Specify; use Codeception\Specify;
use common\models\AccountSession; use common\models\AccountSession;
use tests\codeception\api\unit\TestCase;
use Yii; use Yii;
class LogoutFormTest extends TestCase { class LogoutFormTest extends TestCase {

View File

@ -1,13 +1,13 @@
<?php <?php
namespace tests\codeception\api\models\authentication; namespace api\tests\_support\models\authentication;
use api\components\User\AuthenticationResult; use api\components\User\AuthenticationResult;
use api\models\authentication\RecoverPasswordForm; use api\models\authentication\RecoverPasswordForm;
use api\tests\unit\TestCase;
use Codeception\Specify; use Codeception\Specify;
use common\models\Account; use common\models\Account;
use common\models\EmailActivation; use common\models\EmailActivation;
use tests\codeception\api\unit\TestCase; use common\tests\fixtures\EmailActivationFixture;
use tests\codeception\common\fixtures\EmailActivationFixture;
class RecoverPasswordFormTest extends TestCase { class RecoverPasswordFormTest extends TestCase {
use Specify; use Specify;

Some files were not shown because too many files have changed in this diff Show More