mirror of
https://github.com/elyby/accounts.git
synced 2024-12-02 11:41:05 +05:30
Merge branch 'develop'
This commit is contained in:
commit
b2e3772c41
72
.gitlab-ci.yml
Normal file
72
.gitlab-ci.yml
Normal file
@ -0,0 +1,72 @@
|
||||
stages:
|
||||
- test
|
||||
- build
|
||||
- release
|
||||
|
||||
variables:
|
||||
CONTAINER_IMAGE: registry.ely.by/elyby/accounts
|
||||
|
||||
test:backend:
|
||||
image: jonaskello/docker-and-compose:1.12.1-1.8.0
|
||||
services:
|
||||
- docker:1.12.1-dind
|
||||
stage: test
|
||||
before_script:
|
||||
- docker login -u gitlab-ci -p $CI_BUILD_TOKEN registry.ely.by
|
||||
- echo "$SSH_PRIVATE_KEY" > id_rsa
|
||||
- docker-compose -f tests/docker-compose.yml build --pull testphp
|
||||
after_script:
|
||||
- docker-compose -f tests/docker-compose.yml down -v
|
||||
script:
|
||||
- docker-compose -f tests/docker-compose.yml run --rm testphp ./vendor/bin/codecept run -c tests
|
||||
|
||||
test:frontend:
|
||||
image: node:5.12
|
||||
stage: test
|
||||
cache:
|
||||
paths:
|
||||
- frontend/node_modules
|
||||
script:
|
||||
- cd frontend
|
||||
- npm i --silent
|
||||
- npm run test
|
||||
|
||||
build:production:
|
||||
image: docker:latest
|
||||
stage: build
|
||||
before_script:
|
||||
- docker login -u gitlab-ci -p $CI_BUILD_TOKEN registry.ely.by
|
||||
- echo "$SSH_PRIVATE_KEY" > id_rsa
|
||||
script:
|
||||
- export IMAGE_NAME="$CONTAINER_IMAGE:latest"
|
||||
- docker build --pull -t $IMAGE_NAME .
|
||||
only:
|
||||
- develop
|
||||
- tags
|
||||
|
||||
release:latest:
|
||||
image: docker:latest
|
||||
stage: release
|
||||
variables:
|
||||
GIT_STRATEGY: none
|
||||
before_script:
|
||||
- docker login -u gitlab-ci -p $CI_BUILD_TOKEN registry.ely.by
|
||||
script:
|
||||
- docker push $CONTAINER_IMAGE:latest
|
||||
only:
|
||||
- develop
|
||||
- tags
|
||||
|
||||
release:tag:
|
||||
image: docker:latest
|
||||
stage: release
|
||||
variables:
|
||||
GIT_STRATEGY: none
|
||||
before_script:
|
||||
- docker login -u gitlab-ci -p $CI_BUILD_TOKEN registry.ely.by
|
||||
script:
|
||||
- export IMAGE_NAME="$CONTAINER_IMAGE:$CI_BUILD_TAG"
|
||||
- docker tag $CONTAINER_IMAGE:latest $IMAGE_NAME
|
||||
- docker push $IMAGE_NAME
|
||||
only:
|
||||
- tags
|
116
Dockerfile
116
Dockerfile
@ -1,112 +1,15 @@
|
||||
FROM php:7.0-fpm
|
||||
FROM registry.ely.by/elyby/accounts-php:1.0.0
|
||||
|
||||
ENV PATH $PATH:/root/.composer/vendor/bin
|
||||
|
||||
# Сначала настраиваем всё, что нам нужно на системном уровне
|
||||
RUN apt-get update \
|
||||
&& apt-get -y install \
|
||||
git \
|
||||
g++ \
|
||||
libicu-dev \
|
||||
libmcrypt-dev \
|
||||
zlib1g-dev \
|
||||
bzip2 \
|
||||
libbz2-dev \
|
||||
liblzma-dev \
|
||||
xz-utils \
|
||||
openssh-server \
|
||||
supervisor \
|
||||
--no-install-recommends \
|
||||
--force-yes \
|
||||
|
||||
# PHP расширения
|
||||
&& docker-php-ext-install intl \
|
||||
&& docker-php-ext-install pdo_mysql \
|
||||
&& docker-php-ext-install mbstring \
|
||||
&& docker-php-ext-install mcrypt \
|
||||
&& docker-php-ext-install zip \
|
||||
&& docker-php-ext-install bcmath \
|
||||
&& docker-php-ext-install opcache \
|
||||
|
||||
&& apt-get purge -y g++ \
|
||||
&& apt-get autoremove -y \
|
||||
&& rm -r /var/lib/apt/lists/* \
|
||||
|
||||
# Отключаем сброс глобальных env переменных внутри PHP
|
||||
&& echo "\nclear_env = no" >> /usr/local/etc/php-fpm.conf \
|
||||
|
||||
# Фикс прав на запись для расшаренных папок
|
||||
&& usermod -u 1000 www-data
|
||||
|
||||
# Копипаста из https://github.com/nodejs/docker-node/blob/50b56d39a236fd519eda2231757aa2173e270807/5.12/Dockerfile
|
||||
|
||||
# gpg keys listed at https://github.com/nodejs/node
|
||||
RUN set -ex \
|
||||
&& for key in \
|
||||
9554F04D7259F04124DE6B476D5A82AC7E37093B \
|
||||
94AE36675C464D64BAFA68DD7434390BDBE9B9C5 \
|
||||
0034A06D9D9B0064CE8ADF6BF1747F4AD2306D93 \
|
||||
FD3A5288F042B6850C66B31F09FE44734EB7990E \
|
||||
71DCFD284A79C3B38668286BC97EC7A07EDE3FC1 \
|
||||
DD8F2338BAE7501E3DD5AC78C273792F7D83545D \
|
||||
B9AE9905FFD7803F25714661B63B535A4C206CA9 \
|
||||
C4F0DFFF4E8C1A8236409D08E73BC641CC11F4C8 \
|
||||
; do \
|
||||
gpg --keyserver ha.pool.sks-keyservers.net --recv-keys "$key"; \
|
||||
done
|
||||
|
||||
ENV NPM_CONFIG_LOGLEVEL info
|
||||
ENV NODE_VERSION 5.12.0
|
||||
|
||||
RUN curl -SLO "https://nodejs.org/dist/v$NODE_VERSION/node-v$NODE_VERSION-linux-x64.tar.xz" \
|
||||
&& curl -SLO "https://nodejs.org/dist/v$NODE_VERSION/SHASUMS256.txt.asc" \
|
||||
&& gpg --batch --decrypt --output SHASUMS256.txt SHASUMS256.txt.asc \
|
||||
&& grep " node-v$NODE_VERSION-linux-x64.tar.xz\$" SHASUMS256.txt | sha256sum -c - \
|
||||
&& tar -xJf "node-v$NODE_VERSION-linux-x64.tar.xz" -C /usr/local --strip-components=1 \
|
||||
&& rm "node-v$NODE_VERSION-linux-x64.tar.xz" SHASUMS256.txt.asc SHASUMS256.txt \
|
||||
&& ln -s /usr/local/bin/node /usr/local/bin/nodejs
|
||||
|
||||
ENV COMPOSER_NO_INTERACTION 1
|
||||
ENV COMPOSER_ALLOW_SUPERUSER 1
|
||||
ENV COMPOSER_DISCARD_CHANGES true
|
||||
|
||||
# Composer и его глобальные зависимости
|
||||
RUN curl -sS https://getcomposer.org/installer | php \
|
||||
&& mv composer.phar /usr/local/bin/composer.phar \
|
||||
&& echo '{"github-oauth": {"github.com": "***REMOVED***"}}' > ~/.composer/auth.json \
|
||||
&& composer.phar global require --no-progress "hirak/prestissimo:>=0.3.4"
|
||||
|
||||
COPY ./docker/php/composer.sh /usr/local/bin/composer
|
||||
|
||||
# Конфиг для php
|
||||
COPY ./docker/php/php.ini /usr/local/etc/php/
|
||||
|
||||
# Конфиг для supervisor
|
||||
COPY ./docker/php/supervisord.conf /etc/supervisord.conf
|
||||
|
||||
# wait-for-it
|
||||
COPY ./docker/wait-for-it.sh /usr/local/bin/wait-for-it
|
||||
|
||||
# Наша кавайная точка входа
|
||||
COPY ./docker/php/entrypoint.sh /usr/local/bin/
|
||||
|
||||
RUN chmod a+x /usr/local/bin/composer \
|
||||
&& chmod a+x /usr/local/bin/entrypoint.sh \
|
||||
&& chmod a+x /usr/local/bin/wait-for-it \
|
||||
&& ln -s /usr/local/bin/entrypoint.sh / \
|
||||
&& mkdir /root/.ssh
|
||||
|
||||
COPY id_rsa /root/.ssh
|
||||
COPY id_rsa /root/.ssh/id_rsa
|
||||
|
||||
# Включаем поддержку ssh
|
||||
RUN eval $(ssh-agent -s) \
|
||||
RUN chmod 400 ~/.ssh/id_rsa \
|
||||
&& eval $(ssh-agent -s) \
|
||||
&& ssh-add /root/.ssh/id_rsa \
|
||||
&& touch /root/.ssh/known_hosts \
|
||||
&& ssh-keyscan gitlab.com >> /root/.ssh/known_hosts
|
||||
|
||||
WORKDIR /var/www/html
|
||||
|
||||
# Копируем composer.json в родительскую директорию, которая не будет синкатся с хостом через
|
||||
# Копируем composer.json в родительскую директорию, которая не будет синкаться с хостом через
|
||||
# volume на dev окружении. В entrypoint эта папка будет скопирована обратно.
|
||||
COPY ./composer.json /var/www/composer.json
|
||||
|
||||
@ -128,6 +31,9 @@ RUN cd ../frontend \
|
||||
&& npm install \
|
||||
&& cd -
|
||||
|
||||
# Удаляем ключи из production контейнера на всякий случай
|
||||
RUN rm -rf /root/.ssh
|
||||
|
||||
# Наконец переносим все сорцы внутрь контейнера
|
||||
COPY . /var/www/html
|
||||
|
||||
@ -141,9 +47,3 @@ RUN mkdir -p api/runtime api/web/assets console/runtime \
|
||||
# Копируем билд наружу, чтобы его не затёрло volume в dev режиме
|
||||
&& cp -r ./dist /var/www/dist \
|
||||
&& cd -
|
||||
|
||||
# Экспозим всё под /var/www/html для дальнейшей связки с nginx
|
||||
VOLUME ["/var/www/html"]
|
||||
|
||||
ENTRYPOINT ["entrypoint.sh"]
|
||||
CMD ["/usr/bin/supervisord", "-n", "-c", "/etc/supervisord.conf"]
|
||||
|
126
Dockerfile-dev
126
Dockerfile-dev
@ -1,125 +1,15 @@
|
||||
FROM php:7.0-fpm
|
||||
FROM registry.ely.by/elyby/accounts-php:1.0.0-dev
|
||||
|
||||
ENV PATH $PATH:/root/.composer/vendor/bin
|
||||
|
||||
# Сначала настраиваем всё, что нам нужно на системном уровне
|
||||
RUN apt-get update \
|
||||
&& apt-get -y install \
|
||||
git \
|
||||
g++ \
|
||||
libicu-dev \
|
||||
libmcrypt-dev \
|
||||
zlib1g-dev \
|
||||
bzip2 \
|
||||
libbz2-dev \
|
||||
liblzma-dev \
|
||||
xz-utils \
|
||||
openssh-server \
|
||||
supervisor \
|
||||
--no-install-recommends \
|
||||
--force-yes \
|
||||
|
||||
# PHP расширения
|
||||
&& docker-php-ext-install intl \
|
||||
&& docker-php-ext-install pdo_mysql \
|
||||
&& docker-php-ext-install mbstring \
|
||||
&& docker-php-ext-install mcrypt \
|
||||
&& docker-php-ext-install zip \
|
||||
&& docker-php-ext-install bcmath \
|
||||
&& docker-php-ext-install opcache \
|
||||
|
||||
&& apt-get purge -y g++ \
|
||||
&& apt-get autoremove -y \
|
||||
&& rm -r /var/lib/apt/lists/* \
|
||||
|
||||
# Отключаем сброс глобальных env переменных внутри PHP
|
||||
&& echo "\nclear_env = no" >> /usr/local/etc/php-fpm.conf \
|
||||
|
||||
# Фикс прав на запись для расшаренных папок
|
||||
&& usermod -u 1000 www-data
|
||||
|
||||
# Копипаста из https://github.com/nodejs/docker-node/blob/50b56d39a236fd519eda2231757aa2173e270807/5.12/Dockerfile
|
||||
|
||||
# gpg keys listed at https://github.com/nodejs/node
|
||||
RUN set -ex \
|
||||
&& for key in \
|
||||
9554F04D7259F04124DE6B476D5A82AC7E37093B \
|
||||
94AE36675C464D64BAFA68DD7434390BDBE9B9C5 \
|
||||
0034A06D9D9B0064CE8ADF6BF1747F4AD2306D93 \
|
||||
FD3A5288F042B6850C66B31F09FE44734EB7990E \
|
||||
71DCFD284A79C3B38668286BC97EC7A07EDE3FC1 \
|
||||
DD8F2338BAE7501E3DD5AC78C273792F7D83545D \
|
||||
B9AE9905FFD7803F25714661B63B535A4C206CA9 \
|
||||
C4F0DFFF4E8C1A8236409D08E73BC641CC11F4C8 \
|
||||
; do \
|
||||
gpg --keyserver ha.pool.sks-keyservers.net --recv-keys "$key"; \
|
||||
done
|
||||
|
||||
ENV NPM_CONFIG_LOGLEVEL info
|
||||
ENV NODE_VERSION 5.12.0
|
||||
|
||||
RUN curl -SLO "https://nodejs.org/dist/v$NODE_VERSION/node-v$NODE_VERSION-linux-x64.tar.xz" \
|
||||
&& curl -SLO "https://nodejs.org/dist/v$NODE_VERSION/SHASUMS256.txt.asc" \
|
||||
&& gpg --batch --decrypt --output SHASUMS256.txt SHASUMS256.txt.asc \
|
||||
&& grep " node-v$NODE_VERSION-linux-x64.tar.xz\$" SHASUMS256.txt | sha256sum -c - \
|
||||
&& tar -xJf "node-v$NODE_VERSION-linux-x64.tar.xz" -C /usr/local --strip-components=1 \
|
||||
&& rm "node-v$NODE_VERSION-linux-x64.tar.xz" SHASUMS256.txt.asc SHASUMS256.txt \
|
||||
&& ln -s /usr/local/bin/node /usr/local/bin/nodejs
|
||||
|
||||
# Поставим xdebug отдельно, т.к. потом его потенциально придётся отсюда убирать
|
||||
RUN yes | pecl install xdebug \
|
||||
&& echo "zend_extension=$(find /usr/local/lib/php/extensions/ -name xdebug.so)" > /usr/local/etc/php/conf.d/xdebug.ini \
|
||||
&& echo "xdebug.default_enable=1" >> /usr/local/etc/php/conf.d/xdebug.ini \
|
||||
&& echo "xdebug.remote_enable=1" >> /usr/local/etc/php/conf.d/xdebug.ini \
|
||||
&& echo "xdebug.remote_handler=dbgp" >> /usr/local/etc/php/conf.d/xdebug.ini \
|
||||
&& echo "xdebug.remote_mode=req" >> /usr/local/etc/php/conf.d/xdebug.ini \
|
||||
&& echo "xdebug.remote_autostart=1" >> /usr/local/etc/php/conf.d/xdebug.ini \
|
||||
&& echo "xdebug.remote_port=9000" >> /usr/local/etc/php/conf.d/xdebug.ini \
|
||||
&& echo "xdebug.remote_connect_back=0" >> /usr/local/etc/php/conf.d/xdebug.ini \
|
||||
&& echo "xdebug.cli_color=1" >> /usr/local/etc/php/conf.d/xdebug.ini \
|
||||
&& echo "xdebug.var_display_max_depth=10" >> /usr/local/etc/php/conf.d/xdebug.ini
|
||||
|
||||
ENV COMPOSER_NO_INTERACTION 1
|
||||
ENV COMPOSER_ALLOW_SUPERUSER 1
|
||||
ENV COMPOSER_DISCARD_CHANGES true
|
||||
|
||||
# Composer и его глобальные зависимости
|
||||
RUN curl -sS https://getcomposer.org/installer | php \
|
||||
&& mv composer.phar /usr/local/bin/composer.phar \
|
||||
&& echo '{"github-oauth": {"github.com": "***REMOVED***"}}' > ~/.composer/auth.json \
|
||||
&& composer.phar global require --no-progress "hirak/prestissimo:>=0.3.4"
|
||||
|
||||
COPY ./docker/php/composer.sh /usr/local/bin/composer
|
||||
|
||||
# Конфиг для php
|
||||
COPY ./docker/php/php.ini /usr/local/etc/php/
|
||||
|
||||
# Конфиг для supervisor
|
||||
COPY ./docker/php/supervisord.conf /etc/supervisord.conf
|
||||
|
||||
# wait-for-it
|
||||
COPY ./docker/wait-for-it.sh /usr/local/bin/wait-for-it
|
||||
|
||||
# Наша кавайная точка входа
|
||||
COPY ./docker/php/entrypoint.sh /usr/local/bin/
|
||||
|
||||
RUN chmod a+x /usr/local/bin/composer \
|
||||
&& chmod a+x /usr/local/bin/entrypoint.sh \
|
||||
&& chmod a+x /usr/local/bin/wait-for-it \
|
||||
&& ln -s /usr/local/bin/entrypoint.sh / \
|
||||
&& mkdir /root/.ssh
|
||||
|
||||
COPY id_rsa /root/.ssh
|
||||
COPY id_rsa /root/.ssh/id_rsa
|
||||
|
||||
# Включаем поддержку ssh
|
||||
RUN eval $(ssh-agent -s) \
|
||||
RUN chmod 400 ~/.ssh/id_rsa \
|
||||
&& eval $(ssh-agent -s) \
|
||||
&& ssh-add /root/.ssh/id_rsa \
|
||||
&& touch /root/.ssh/known_hosts \
|
||||
&& ssh-keyscan gitlab.com >> /root/.ssh/known_hosts
|
||||
|
||||
WORKDIR /var/www/html
|
||||
|
||||
# Копируем composer.json в родительскую директорию, которая не будет синкатся с хостом через
|
||||
# Копируем composer.json в родительскую директорию, которая не будет синкаться с хостом через
|
||||
# volume на dev окружении. В entrypoint эта папка будет скопирована обратно.
|
||||
COPY ./composer.json /var/www/composer.json
|
||||
|
||||
@ -154,9 +44,3 @@ RUN mkdir -p api/runtime api/web/assets console/runtime \
|
||||
# Копируем билд наружу, чтобы его не затёрло volume в dev режиме
|
||||
&& cp -r ./dist /var/www/dist \
|
||||
&& cd -
|
||||
|
||||
# Экспозим всё под /var/www/html для дальнейшей связки с nginx
|
||||
VOLUME ["/var/www/html"]
|
||||
|
||||
ENTRYPOINT ["entrypoint.sh"]
|
||||
CMD ["/usr/bin/supervisord", "-n", "-c", "/etc/supervisord.conf"]
|
||||
|
@ -6,9 +6,12 @@
|
||||
[docker](https://docs.docker.com/engine/installation/) и его
|
||||
[docker-compose](https://docs.docker.com/compose/install/).
|
||||
|
||||
Кроме того, нужно установить, настроить и запустить [nginx-proxy](https://gitlab.com/elyby/nginx-proxy)
|
||||
За тем нужно установить, настроить и запустить [nginx-proxy](https://gitlab.com/elyby/nginx-proxy)
|
||||
контейнер. Это делается один раз в рамках системы и в дальнейшем используется и для других проектов.
|
||||
|
||||
Также необходимо иметь доступ к `registry.ely.by`. Для этого выполнить команду `docker login registry.ely.by`,
|
||||
ввести свой логин и пароль. Если доступа нету, то нужно его попросить у кого-нибудь, кто может его выдать.
|
||||
|
||||
За тем сливаем репозиторий:
|
||||
|
||||
```sh
|
||||
|
@ -3,6 +3,8 @@ namespace api\components\User;
|
||||
|
||||
use api\models\AccountIdentity;
|
||||
use common\models\AccountSession;
|
||||
use DateInterval;
|
||||
use DateTime;
|
||||
use Emarref\Jwt\Algorithm\AlgorithmInterface;
|
||||
use Emarref\Jwt\Algorithm\Hs256;
|
||||
use Emarref\Jwt\Claim;
|
||||
@ -33,7 +35,9 @@ class Component extends YiiUserComponent {
|
||||
|
||||
public $secret;
|
||||
|
||||
public $expirationTimeout = 3600; // 1h
|
||||
public $expirationTimeout = 'PT1H';
|
||||
|
||||
public $sessionTimeout = 'P7D';
|
||||
|
||||
public function init() {
|
||||
parent::init();
|
||||
@ -73,7 +77,7 @@ class Component extends YiiUserComponent {
|
||||
$session = null;
|
||||
// Если мы не сохраняем сессию, то токен должен жить подольше, чтобы
|
||||
// не прогорала сессия во время работы с аккаунтом
|
||||
$token->addClaim(new Claim\Expiration(time() + 60 * 60 * 24 * 7));
|
||||
$token->addClaim(new Claim\Expiration((new DateTime())->add(new DateInterval($this->sessionTimeout))));
|
||||
}
|
||||
|
||||
$jwt = $this->serializeToken($token);
|
||||
@ -135,8 +139,8 @@ class Component extends YiiUserComponent {
|
||||
* - Юзер не авторизован
|
||||
* - Почему-то нет заголовка с токеном
|
||||
* - Во время проверки токена возникла ошибка, что привело к исключению
|
||||
* - В токене не найдено ключа сессии. Такое возможно, если юзер выбрал "не запоминать меня" или просто старые
|
||||
* токены, без поддержки сохранения используемой сессии
|
||||
* - В токене не найдено ключа сессии. Такое возможно, если юзер выбрал "не запоминать меня"
|
||||
* или просто старые токены, без поддержки сохранения используемой сессии
|
||||
*
|
||||
* @return AccountSession|null
|
||||
*/
|
||||
@ -187,14 +191,14 @@ class Component extends YiiUserComponent {
|
||||
* @return Claim\AbstractClaim[]
|
||||
*/
|
||||
protected function getClaims(IdentityInterface $identity) {
|
||||
$currentTime = time();
|
||||
$currentTime = new DateTime();
|
||||
$hostInfo = Yii::$app->request->hostInfo;
|
||||
|
||||
return [
|
||||
new Claim\Audience($hostInfo),
|
||||
new Claim\Issuer($hostInfo),
|
||||
new Claim\IssuedAt($currentTime),
|
||||
new Claim\Expiration($currentTime + $this->expirationTimeout),
|
||||
new Claim\Expiration($currentTime->add(new DateInterval($this->expirationTimeout))),
|
||||
new Claim\JwtId($identity->getId()),
|
||||
];
|
||||
}
|
||||
|
@ -2,6 +2,8 @@
|
||||
namespace api\components\User;
|
||||
|
||||
use common\models\AccountSession;
|
||||
use DateInterval;
|
||||
use DateTime;
|
||||
use Yii;
|
||||
use yii\web\IdentityInterface;
|
||||
|
||||
@ -45,9 +47,13 @@ class LoginResult {
|
||||
public function getAsResponse() {
|
||||
/** @var Component $component */
|
||||
$component = Yii::$app->user;
|
||||
|
||||
$now = new DateTime();
|
||||
$expiresIn = (clone $now)->add(new DateInterval($component->expirationTimeout));
|
||||
|
||||
$response = [
|
||||
'access_token' => $this->getJwt(),
|
||||
'expires_in' => $component->expirationTimeout,
|
||||
'expires_in' => $expiresIn->getTimestamp() - $now->getTimestamp(),
|
||||
];
|
||||
|
||||
$session = $this->getSession();
|
||||
|
@ -1,6 +1,8 @@
|
||||
<?php
|
||||
namespace api\components\User;
|
||||
|
||||
use DateInterval;
|
||||
use DateTime;
|
||||
use Yii;
|
||||
use yii\web\IdentityInterface;
|
||||
|
||||
@ -33,9 +35,12 @@ class RenewResult {
|
||||
/** @var Component $component */
|
||||
$component = Yii::$app->user;
|
||||
|
||||
$now = new DateTime();
|
||||
$expiresIn = (clone $now)->add(new DateInterval($component->expirationTimeout));
|
||||
|
||||
return [
|
||||
'access_token' => $this->getJwt(),
|
||||
'expires_in' => $component->expirationTimeout,
|
||||
'expires_in' => $expiresIn->getTimestamp() - $now->getTimestamp(),
|
||||
];
|
||||
}
|
||||
|
||||
|
@ -12,8 +12,5 @@ return [
|
||||
'class' => yii\debug\Module::class,
|
||||
'allowedIPs' => ['*'],
|
||||
],
|
||||
'gii' => [
|
||||
'class' => yii\gii\Module::class,
|
||||
],
|
||||
],
|
||||
];
|
||||
|
@ -34,12 +34,14 @@ return [
|
||||
[
|
||||
'class' => yii\log\FileTarget::class,
|
||||
'levels' => ['error', 'info'],
|
||||
'logVars' => [],
|
||||
'categories' => ['legacy-authserver'],
|
||||
'logFile' => '@runtime/logs/authserver.log',
|
||||
],
|
||||
[
|
||||
'class' => yii\log\FileTarget::class,
|
||||
'levels' => ['error', 'info'],
|
||||
'logVars' => [],
|
||||
'categories' => ['session'],
|
||||
'logFile' => '@runtime/logs/session.log',
|
||||
],
|
||||
|
@ -65,7 +65,6 @@ class AccountsController extends Controller {
|
||||
'username' => $account->username,
|
||||
'email' => $account->email,
|
||||
'lang' => $account->lang,
|
||||
'shouldChangePassword' => $account->password_hash_strategy === Account::PASS_HASH_STRATEGY_OLD_ELY,
|
||||
'isActive' => $account->status === Account::STATUS_ACTIVE,
|
||||
'passwordChangedAt' => $account->password_changed_at,
|
||||
'hasMojangUsernameCollision' => $account->hasMojangUsernameCollision(),
|
||||
|
@ -4,6 +4,7 @@ namespace api\controllers;
|
||||
use api\filters\ActiveUserRule;
|
||||
use common\components\oauth\Exception\AcceptRequiredException;
|
||||
use common\components\oauth\Exception\AccessDeniedException;
|
||||
use common\models\Account;
|
||||
use common\models\OauthClient;
|
||||
use common\models\OauthScope;
|
||||
use League\OAuth2\Server\Exception\OAuthException;
|
||||
@ -108,7 +109,7 @@ class OauthController extends Controller {
|
||||
/** @var \common\models\OauthClient $clientModel */
|
||||
$clientModel = OauthClient::findOne($client->getId());
|
||||
|
||||
if (!$account->canAutoApprove($clientModel, $authParams['scopes'])) {
|
||||
if (!$this->canAutoApprove($account, $clientModel, $authParams)) {
|
||||
$isAccept = Yii::$app->request->post('accept');
|
||||
if ($isAccept === null) {
|
||||
throw new AcceptRequiredException();
|
||||
@ -197,6 +198,36 @@ class OauthController extends Controller {
|
||||
$this->getServer()->addGrantType(new RefreshTokenGrant());
|
||||
}
|
||||
|
||||
/**
|
||||
* Метод проверяет, может ли текущий пользователь быть автоматически авторизован
|
||||
* для указанного клиента без запроса доступа к необходимому списку прав
|
||||
*
|
||||
* @param Account $account
|
||||
* @param OauthClient $client
|
||||
* @param array $oauthParams
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
private function canAutoApprove(Account $account, OauthClient $client, array $oauthParams) : bool {
|
||||
if ($client->is_trusted) {
|
||||
return true;
|
||||
}
|
||||
|
||||
/** @var \League\OAuth2\Server\Entity\ScopeEntity[] $scopes */
|
||||
$scopes = $oauthParams['scopes'];
|
||||
|
||||
/** @var \common\models\OauthSession|null $session */
|
||||
$session = $account->getOauthSessions()->andWhere(['client_id' => $client->id])->one();
|
||||
if ($session !== null) {
|
||||
$existScopes = $session->getScopes()->members();
|
||||
if (empty(array_diff(array_keys($scopes), $existScopes))) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array $queryParams
|
||||
* @param OauthClient $clientModel
|
||||
|
@ -3,6 +3,7 @@ namespace api\models\authentication;
|
||||
|
||||
use api\models\AccountIdentity;
|
||||
use api\models\base\KeyConfirmationForm;
|
||||
use api\models\profile\ChangeUsernameForm;
|
||||
use common\models\Account;
|
||||
use common\models\EmailActivation;
|
||||
use Yii;
|
||||
@ -16,7 +17,7 @@ class ConfirmEmailForm extends KeyConfirmationForm {
|
||||
}
|
||||
|
||||
$confirmModel = $this->getActivationCodeModel();
|
||||
if ($confirmModel->type != EmailActivation::TYPE_REGISTRATION_EMAIL_CONFIRMATION) {
|
||||
if ($confirmModel->type !== EmailActivation::TYPE_REGISTRATION_EMAIL_CONFIRMATION) {
|
||||
$confirmModel->delete();
|
||||
// TODO: вот где-то здесь нужно ещё попутно сгенерировать соответствующую ошибку
|
||||
return false;
|
||||
@ -34,6 +35,9 @@ class ConfirmEmailForm extends KeyConfirmationForm {
|
||||
throw new ErrorException('Unable activate user account.');
|
||||
}
|
||||
|
||||
$changeUsernameForm = new ChangeUsernameForm();
|
||||
$changeUsernameForm->createEventTask($account->id, $account->username, null);
|
||||
|
||||
$transaction->commit();
|
||||
} catch (ErrorException $e) {
|
||||
$transaction->rollBack();
|
||||
|
@ -77,7 +77,7 @@ class LoginForm extends ApiForm {
|
||||
}
|
||||
|
||||
$account = $this->getAccount();
|
||||
if ($account->password_hash_strategy === Account::PASS_HASH_STRATEGY_OLD_ELY) {
|
||||
if ($account->password_hash_strategy !== Account::PASS_HASH_STRATEGY_YII2) {
|
||||
$account->setPassword($this->password);
|
||||
$account->save();
|
||||
}
|
||||
|
@ -5,7 +5,7 @@ use api\models\AccountIdentity;
|
||||
use api\models\base\KeyConfirmationForm;
|
||||
use common\helpers\Error as E;
|
||||
use common\models\EmailActivation;
|
||||
use common\validators\PasswordValidate;
|
||||
use common\validators\PasswordValidator;
|
||||
use Yii;
|
||||
use yii\base\ErrorException;
|
||||
|
||||
@ -19,7 +19,7 @@ class RecoverPasswordForm extends KeyConfirmationForm {
|
||||
return array_merge(parent::rules(), [
|
||||
['newPassword', 'required', 'message' => E::NEW_PASSWORD_REQUIRED],
|
||||
['newRePassword', 'required', 'message' => E::NEW_RE_PASSWORD_REQUIRED],
|
||||
['newPassword', PasswordValidate::class],
|
||||
['newPassword', PasswordValidator::class],
|
||||
['newRePassword', 'validatePasswordAndRePasswordMatch'],
|
||||
]);
|
||||
}
|
||||
|
@ -4,19 +4,21 @@ namespace api\models\authentication;
|
||||
use api\components\ReCaptcha\Validator as ReCaptchaValidator;
|
||||
use api\models\base\ApiForm;
|
||||
use common\helpers\Error as E;
|
||||
use api\models\profile\ChangeUsernameForm;
|
||||
use common\components\UserFriendlyRandomKey;
|
||||
use common\models\Account;
|
||||
use common\models\confirmations\RegistrationConfirmation;
|
||||
use common\models\EmailActivation;
|
||||
use common\models\UsernameHistory;
|
||||
use common\validators\EmailValidator;
|
||||
use common\validators\LanguageValidator;
|
||||
use common\validators\PasswordValidate;
|
||||
use common\validators\PasswordValidator;
|
||||
use common\validators\UsernameValidator;
|
||||
use Exception;
|
||||
use Ramsey\Uuid\Uuid;
|
||||
use Yii;
|
||||
use yii\base\ErrorException;
|
||||
use yii\base\InvalidConfigException;
|
||||
use yii\helpers\ArrayHelper;
|
||||
use const common\LATEST_RULES_VERSION;
|
||||
|
||||
class RegistrationForm extends ApiForm {
|
||||
@ -40,34 +42,19 @@ class RegistrationForm extends ApiForm {
|
||||
['captcha', ReCaptchaValidator::class],
|
||||
['rulesAgreement', 'required', 'message' => E::RULES_AGREEMENT_REQUIRED],
|
||||
|
||||
['username', 'validateUsername', 'skipOnEmpty' => false],
|
||||
['email', 'validateEmail', 'skipOnEmpty' => false],
|
||||
['username', UsernameValidator::class],
|
||||
['email', EmailValidator::class],
|
||||
|
||||
['password', 'required', 'message' => E::PASSWORD_REQUIRED],
|
||||
['rePassword', 'required', 'message' => E::RE_PASSWORD_REQUIRED],
|
||||
['password', PasswordValidate::class],
|
||||
['password', PasswordValidator::class],
|
||||
['rePassword', 'validatePasswordAndRePasswordMatch'],
|
||||
|
||||
['lang', LanguageValidator::class],
|
||||
['lang', 'default', 'value' => 'en'],
|
||||
];
|
||||
}
|
||||
|
||||
public function validateUsername() {
|
||||
$account = new Account();
|
||||
$account->username = $this->username;
|
||||
if (!$account->validate(['username'])) {
|
||||
$this->addErrors($account->getErrors());
|
||||
}
|
||||
}
|
||||
|
||||
public function validateEmail() {
|
||||
$account = new Account();
|
||||
$account->email = $this->email;
|
||||
if (!$account->validate(['email'])) {
|
||||
$this->addErrors($account->getErrors());
|
||||
}
|
||||
}
|
||||
|
||||
public function validatePasswordAndRePasswordMatch($attribute) {
|
||||
if (!$this->hasErrors()) {
|
||||
if ($this->password !== $this->rePassword) {
|
||||
@ -81,7 +68,7 @@ class RegistrationForm extends ApiForm {
|
||||
* @throws Exception
|
||||
*/
|
||||
public function signup() {
|
||||
if (!$this->validate()) {
|
||||
if (!$this->validate() && !$this->canContinue($this->getFirstErrors())) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@ -118,9 +105,6 @@ class RegistrationForm extends ApiForm {
|
||||
|
||||
$this->sendMail($emailActivation, $account);
|
||||
|
||||
$changeUsernameForm = new ChangeUsernameForm();
|
||||
$changeUsernameForm->createEventTask($account->id, $account->username, null);
|
||||
|
||||
$transaction->commit();
|
||||
} catch (Exception $e) {
|
||||
$transaction->rollBack();
|
||||
@ -161,4 +145,43 @@ class RegistrationForm extends ApiForm {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Метод проверяет, можно ли занять указанный при регистрации ник или e-mail. Так случается,
|
||||
* что пользователи вводят неправильный e-mail или ник, после замечают это и пытаются вновь
|
||||
* выпонить регистрацию. Мы не будем им мешать и просто удаляем существующие недозарегистрированные
|
||||
* аккаунты, позволяя им зарегистрироваться.
|
||||
*
|
||||
* @param array $errors массив, где ключ - это поле, а значение - первая ошибка из нашего
|
||||
* стандартного словаря ошибок
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
protected function canContinue(array $errors) : bool {
|
||||
if (ArrayHelper::getValue($errors, 'username') === E::USERNAME_NOT_AVAILABLE) {
|
||||
$duplicatedUsername = Account::findOne([
|
||||
'username' => $this->username,
|
||||
'status' => Account::STATUS_REGISTERED,
|
||||
]);
|
||||
|
||||
if ($duplicatedUsername !== null) {
|
||||
$duplicatedUsername->delete();
|
||||
unset($errors['username']);
|
||||
}
|
||||
}
|
||||
|
||||
if (ArrayHelper::getValue($errors, 'email') === E::EMAIL_NOT_AVAILABLE) {
|
||||
$duplicatedEmail = Account::findOne([
|
||||
'email' => $this->email,
|
||||
'status' => Account::STATUS_REGISTERED,
|
||||
]);
|
||||
|
||||
if ($duplicatedEmail !== null) {
|
||||
$duplicatedEmail->delete();
|
||||
unset($errors['email']);
|
||||
}
|
||||
}
|
||||
|
||||
return empty($errors);
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -21,7 +21,7 @@ class AcceptRulesForm extends ApiForm {
|
||||
public function agreeWithLatestRules() : bool {
|
||||
$account = $this->getAccount();
|
||||
$account->rules_agreement_version = LATEST_RULES_VERSION;
|
||||
if (!$account->save(false)) {
|
||||
if (!$account->save()) {
|
||||
throw new ErrorException('Cannot set user rules version');
|
||||
}
|
||||
|
||||
|
@ -2,10 +2,10 @@
|
||||
namespace api\models\profile\ChangeEmail;
|
||||
|
||||
use api\models\base\KeyConfirmationForm;
|
||||
use common\helpers\Error as E;
|
||||
use common\models\Account;
|
||||
use common\models\confirmations\NewEmailConfirmation;
|
||||
use common\models\EmailActivation;
|
||||
use common\validators\EmailValidator;
|
||||
use Yii;
|
||||
use yii\base\ErrorException;
|
||||
use yii\base\Exception;
|
||||
@ -25,26 +25,14 @@ class NewEmailForm extends KeyConfirmationForm {
|
||||
parent::__construct($config);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return Account
|
||||
*/
|
||||
public function getAccount() {
|
||||
return $this->account;
|
||||
}
|
||||
|
||||
public function rules() {
|
||||
return array_merge(parent::rules(), [
|
||||
['email', 'required', 'message' => E::EMAIL_REQUIRED],
|
||||
['email', 'validateEmail'],
|
||||
['email', EmailValidator::class],
|
||||
]);
|
||||
}
|
||||
|
||||
public function validateEmail() {
|
||||
$account = new Account();
|
||||
$account->email = $this->email;
|
||||
if (!$account->validate(['email'])) {
|
||||
$this->addErrors($account->getErrors());
|
||||
}
|
||||
public function getAccount() : Account {
|
||||
return $this->account;
|
||||
}
|
||||
|
||||
public function sendNewEmailConfirmation() {
|
||||
|
@ -5,7 +5,7 @@ use api\models\base\ApiForm;
|
||||
use api\validators\PasswordRequiredValidator;
|
||||
use common\helpers\Error as E;
|
||||
use common\models\Account;
|
||||
use common\validators\PasswordValidate;
|
||||
use common\validators\PasswordValidator;
|
||||
use Yii;
|
||||
use yii\base\ErrorException;
|
||||
use yii\helpers\ArrayHelper;
|
||||
@ -37,7 +37,7 @@ class ChangePasswordForm extends ApiForm {
|
||||
return ArrayHelper::merge(parent::rules(), [
|
||||
['newPassword', 'required', 'message' => E::NEW_PASSWORD_REQUIRED],
|
||||
['newRePassword', 'required', 'message' => E::NEW_RE_PASSWORD_REQUIRED],
|
||||
['newPassword', PasswordValidate::class],
|
||||
['newPassword', PasswordValidator::class],
|
||||
['newRePassword', 'validatePasswordAndRePasswordMatch'],
|
||||
['logoutAll', 'boolean'],
|
||||
['password', PasswordRequiredValidator::class, 'account' => $this->_account],
|
||||
|
@ -4,11 +4,10 @@ namespace api\models\profile;
|
||||
use api\models\AccountIdentity;
|
||||
use api\models\base\ApiForm;
|
||||
use api\validators\PasswordRequiredValidator;
|
||||
use common\helpers\Error;
|
||||
use common\helpers\Amqp;
|
||||
use common\models\Account;
|
||||
use common\models\amqp\UsernameChanged;
|
||||
use common\models\UsernameHistory;
|
||||
use common\validators\UsernameValidator;
|
||||
use Exception;
|
||||
use PhpAmqpLib\Message\AMQPMessage;
|
||||
use Yii;
|
||||
@ -22,20 +21,13 @@ class ChangeUsernameForm extends ApiForm {
|
||||
|
||||
public function rules() {
|
||||
return [
|
||||
['username', 'required', 'message' => Error::USERNAME_REQUIRED],
|
||||
['username', 'validateUsername'],
|
||||
['username', UsernameValidator::class, 'accountCallback' => function() {
|
||||
return $this->getAccount()->id;
|
||||
}],
|
||||
['password', PasswordRequiredValidator::class],
|
||||
];
|
||||
}
|
||||
|
||||
public function validateUsername($attribute) {
|
||||
$account = new Account();
|
||||
$account->username = $this->$attribute;
|
||||
if (!$account->validate(['username'])) {
|
||||
$this->addErrors($account->getErrors());
|
||||
}
|
||||
}
|
||||
|
||||
public function change() {
|
||||
if (!$this->validate()) {
|
||||
return false;
|
||||
|
@ -32,7 +32,7 @@ class ApiController extends Controller {
|
||||
// ник пользователь не сменил его на нечто иное
|
||||
$account = null;
|
||||
if ($record !== null) {
|
||||
if ($record->findNext($at) !== null || $record->account->username === $record->username) {
|
||||
if ($record->account->username === $record->username || $record->findNext($at) !== null) {
|
||||
$account = $record->account;
|
||||
}
|
||||
}
|
||||
|
@ -90,6 +90,7 @@ class JoinForm extends Model {
|
||||
}
|
||||
|
||||
$validator = new UuidValidator();
|
||||
$validator->allowNil = false;
|
||||
$validator->validateAttribute($this, $attribute);
|
||||
|
||||
if ($this->hasErrors($attribute)) {
|
||||
|
@ -1,7 +1,7 @@
|
||||
<?php
|
||||
require __DIR__ . '/../../vendor/autoload.php';
|
||||
|
||||
defined('YII_DEBUG') or define('YII_DEBUG', (boolean)getenv('YII_DEBUG'));
|
||||
defined('YII_DEBUG') or define('YII_DEBUG', in_array(getenv('YII_DEBUG'), ['false', '1']));
|
||||
defined('YII_ENV') or define('YII_ENV', getenv('YII_ENV'));
|
||||
|
||||
require __DIR__ . '/../../vendor/yiisoft/yii2/Yii.php';
|
||||
|
@ -4,7 +4,7 @@ namespace common\components\Mojang;
|
||||
use common\components\Mojang\exceptions\MojangApiException;
|
||||
use common\components\Mojang\exceptions\NoContentException;
|
||||
use common\components\Mojang\response\UsernameToUUIDResponse;
|
||||
use GuzzleHttp\Client as GuzzleClient;
|
||||
use Yii;
|
||||
|
||||
class Api {
|
||||
|
||||
@ -23,7 +23,7 @@ class Api {
|
||||
$query['atTime'] = $atTime;
|
||||
}
|
||||
|
||||
$response = $this->createClient()->get($this->buildUsernameToUUIDRoute($username), $query);
|
||||
$response = $this->getClient()->get($this->buildUsernameToUUIDRoute($username), $query);
|
||||
if ($response->getStatusCode() === 204) {
|
||||
throw new NoContentException('Username not found');
|
||||
} elseif ($response->getStatusCode() !== 200) {
|
||||
@ -40,8 +40,11 @@ class Api {
|
||||
return $responseObj;
|
||||
}
|
||||
|
||||
protected function createClient() {
|
||||
return new GuzzleClient();
|
||||
/**
|
||||
* @return \GuzzleHttp\Client
|
||||
*/
|
||||
protected function getClient() {
|
||||
return Yii::$app->guzzle;
|
||||
}
|
||||
|
||||
protected function buildUsernameToUUIDRoute($username) {
|
||||
|
@ -9,7 +9,7 @@ class UserFriendlyRandomKey {
|
||||
$numChars = strlen($chars);
|
||||
$key = '';
|
||||
for ($i = 0; $i < $length; $i++) {
|
||||
$key .= substr($chars, rand(1, $numChars) - 1, 1);
|
||||
$key .= $chars[random_int(0, $numChars - 1)];
|
||||
}
|
||||
|
||||
return $key;
|
||||
|
@ -54,7 +54,7 @@ class AuthCodeStorage extends AbstractStorage implements AuthCodeInterface {
|
||||
* @inheritdoc
|
||||
*/
|
||||
public function getScopes(OriginalAuthCodeEntity $token) {
|
||||
$result = (new Set($this->dataTable, $token->getId(), 'scopes'));
|
||||
$result = new Set($this->dataTable, $token->getId(), 'scopes');
|
||||
$response = [];
|
||||
foreach ($result as $scope) {
|
||||
// TODO: нужно проверить все выданные скоупы на их существование
|
||||
|
@ -57,11 +57,10 @@ class AccessTokenStorage extends AbstractStorage implements AccessTokenInterface
|
||||
* @inheritdoc
|
||||
*/
|
||||
public function create($token, $expireTime, $sessionId) {
|
||||
$model = new OauthAccessToken([
|
||||
'access_token' => $token,
|
||||
'expire_time' => $expireTime,
|
||||
'session_id' => $sessionId,
|
||||
]);
|
||||
$model = new OauthAccessToken();
|
||||
$model->access_token = $token;
|
||||
$model->expire_time = $expireTime;
|
||||
$model->session_id = $sessionId;
|
||||
|
||||
if (!$model->save()) {
|
||||
throw new Exception('Cannot save ' . OauthAccessToken::class . ' model.');
|
||||
|
@ -4,6 +4,7 @@ namespace common\components\oauth\Storage\Yii2;
|
||||
use common\components\oauth\Entity\AuthCodeEntity;
|
||||
use common\components\oauth\Entity\SessionEntity;
|
||||
use common\models\OauthSession;
|
||||
use ErrorException;
|
||||
use League\OAuth2\Server\Entity\AccessTokenEntity as OriginalAccessTokenEntity;
|
||||
use League\OAuth2\Server\Entity\AuthCodeEntity as OriginalAuthCodeEntity;
|
||||
use League\OAuth2\Server\Entity\ScopeEntity;
|
||||
@ -67,7 +68,7 @@ class SessionStorage extends AbstractStorage implements SessionInterface {
|
||||
*/
|
||||
public function getByAuthCode(OriginalAuthCodeEntity $authCode) {
|
||||
if (!$authCode instanceof AuthCodeEntity) {
|
||||
throw new \ErrorException('This module assumes that $authCode typeof ' . AuthCodeEntity::class);
|
||||
throw new ErrorException('This module assumes that $authCode typeof ' . AuthCodeEntity::class);
|
||||
}
|
||||
|
||||
return $this->getSession($authCode->getSessionId());
|
||||
@ -99,11 +100,11 @@ class SessionStorage extends AbstractStorage implements SessionInterface {
|
||||
])->scalar();
|
||||
|
||||
if ($sessionId === false) {
|
||||
$model = new OauthSession([
|
||||
'client_id' => $clientId,
|
||||
'owner_type' => $ownerType,
|
||||
'owner_id' => $ownerId,
|
||||
]);
|
||||
$model = new OauthSession();
|
||||
$model->client_id = $clientId;
|
||||
$model->owner_type = $ownerType;
|
||||
$model->owner_id = $ownerId;
|
||||
$model->client_redirect_uri = $clientRedirectUri;
|
||||
|
||||
if (!$model->save()) {
|
||||
throw new Exception('Cannot save ' . OauthSession::class . ' model.');
|
||||
|
@ -2,10 +2,9 @@
|
||||
namespace common\components\oauth\Util\KeyAlgorithm;
|
||||
|
||||
use League\OAuth2\Server\Util\KeyAlgorithm\DefaultAlgorithm;
|
||||
use League\OAuth2\Server\Util\KeyAlgorithm\KeyAlgorithmInterface;
|
||||
use Ramsey\Uuid\Uuid;
|
||||
|
||||
class UuidAlgorithm extends DefaultAlgorithm implements KeyAlgorithmInterface {
|
||||
class UuidAlgorithm extends DefaultAlgorithm {
|
||||
|
||||
/**
|
||||
* @inheritdoc
|
||||
|
@ -2,7 +2,6 @@
|
||||
namespace common\helpers;
|
||||
|
||||
use common\components\RabbitMQ\Helper;
|
||||
use Yii;
|
||||
|
||||
class Amqp extends Helper {
|
||||
|
||||
|
@ -1,9 +1,10 @@
|
||||
<?php
|
||||
use yii\helpers\Html;
|
||||
/**
|
||||
* @var $this \yii\web\View view component instance
|
||||
* @var $message \yii\mail\MessageInterface the message being composed
|
||||
* @var $content string main view render result
|
||||
*/
|
||||
|
||||
/* @var $this \yii\web\View view component instance */
|
||||
/* @var $message \yii\mail\MessageInterface the message being composed */
|
||||
/* @var $content string main view render result */
|
||||
?>
|
||||
<?php $this->beginPage() ?>
|
||||
<?php $this->beginBody() ?>
|
||||
|
@ -1,10 +1,7 @@
|
||||
<?php
|
||||
namespace common\models;
|
||||
|
||||
use common\helpers\Error as E;
|
||||
use common\components\UserPass;
|
||||
use common\validators\LanguageValidator;
|
||||
use Ely\Yii2\TempmailValidator;
|
||||
use Yii;
|
||||
use yii\base\InvalidConfigException;
|
||||
use yii\behaviors\TimestampBehavior;
|
||||
@ -60,31 +57,6 @@ class Account extends ActiveRecord {
|
||||
];
|
||||
}
|
||||
|
||||
public function rules() {
|
||||
return [
|
||||
[['username'], 'filter', 'filter' => 'trim'],
|
||||
[['username'], 'required', 'message' => E::USERNAME_REQUIRED],
|
||||
[['username'], 'string', 'min' => 3, 'max' => 21,
|
||||
'tooShort' => E::USERNAME_TOO_SHORT,
|
||||
'tooLong' => E::USERNAME_TOO_LONG,
|
||||
],
|
||||
[['username'], 'match', 'pattern' => '/^[\p{L}\d-_\.!?#$%^&*()\[\]:;]+$/u',
|
||||
'message' => E::USERNAME_INVALID,
|
||||
],
|
||||
[['username'], 'unique', 'message' => E::USERNAME_NOT_AVAILABLE],
|
||||
|
||||
[['email'], 'filter', 'filter' => 'trim'],
|
||||
[['email'], 'required', 'message' => E::EMAIL_REQUIRED],
|
||||
[['email'], 'string', 'max' => 255, 'tooLong' => E::EMAIL_TOO_LONG],
|
||||
[['email'], 'email', 'checkDNS' => true, 'enableIDN' => true, 'message' => E::EMAIL_INVALID],
|
||||
[['email'], TempmailValidator::class, 'message' => E::EMAIL_IS_TEMPMAIL],
|
||||
[['email'], 'unique', 'message' => E::EMAIL_NOT_AVAILABLE],
|
||||
|
||||
[['lang'], LanguageValidator::class],
|
||||
[['lang'], 'default', 'value' => 'en'],
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* Validates password
|
||||
*
|
||||
@ -138,34 +110,6 @@ class Account extends ActiveRecord {
|
||||
return $this->hasMany(AccountSession::class, ['account_id' => 'id']);
|
||||
}
|
||||
|
||||
/**
|
||||
* Метод проверяет, может ли текущий пользователь быть автоматически авторизован
|
||||
* для указанного клиента без запроса доступа к необходимому списку прав
|
||||
*
|
||||
* @param OauthClient $client
|
||||
* @param \League\OAuth2\Server\Entity\ScopeEntity[] $scopes
|
||||
*
|
||||
* TODO: этому методу здесь не место.
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function canAutoApprove(OauthClient $client, array $scopes = []) : bool {
|
||||
if ($client->is_trusted) {
|
||||
return true;
|
||||
}
|
||||
|
||||
/** @var OauthSession|null $session */
|
||||
$session = $this->getOauthSessions()->andWhere(['client_id' => $client->id])->one();
|
||||
if ($session !== null) {
|
||||
$existScopes = $session->getScopes()->members();
|
||||
if (empty(array_diff(array_keys($scopes), $existScopes))) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Выполняет проверку, принадлежит ли этому нику аккаунт у Mojang
|
||||
*
|
||||
|
@ -5,14 +5,15 @@ use common\components\redis\Set;
|
||||
use yii\db\ActiveRecord;
|
||||
|
||||
/**
|
||||
* This is the model class for table "oauth_access_tokens".
|
||||
*
|
||||
* Поля:
|
||||
* @property string $access_token
|
||||
* @property string $session_id
|
||||
* @property integer $expire_time
|
||||
*
|
||||
* Геттеры:
|
||||
* @property Set $scopes
|
||||
*
|
||||
* Отношения:
|
||||
* @property OauthSession $session
|
||||
*/
|
||||
class OauthAccessToken extends ActiveRecord {
|
||||
@ -26,7 +27,7 @@ class OauthAccessToken extends ActiveRecord {
|
||||
}
|
||||
|
||||
public function getScopes() {
|
||||
return new Set($this->getDb()->getSchema()->getRawTableName($this->tableName()), $this->access_token, 'scopes');
|
||||
return new Set(static::getDb()->getSchema()->getRawTableName(static::tableName()), $this->access_token, 'scopes');
|
||||
}
|
||||
|
||||
public function beforeDelete() {
|
||||
|
@ -1,7 +1,6 @@
|
||||
<?php
|
||||
namespace common\models;
|
||||
|
||||
use Yii;
|
||||
use yii\db\ActiveRecord;
|
||||
|
||||
/**
|
||||
|
@ -2,7 +2,6 @@
|
||||
namespace common\models;
|
||||
|
||||
use common\components\redis\Set;
|
||||
use Yii;
|
||||
use yii\db\ActiveRecord;
|
||||
|
||||
/**
|
||||
@ -38,7 +37,7 @@ class OauthSession extends ActiveRecord {
|
||||
}
|
||||
|
||||
public function getScopes() {
|
||||
return new Set($this->getDb()->getSchema()->getRawTableName($this->tableName()), $this->id, 'scopes');
|
||||
return new Set(static::getDb()->getSchema()->getRawTableName(static::tableName()), $this->id, 'scopes');
|
||||
}
|
||||
|
||||
public function beforeDelete() {
|
||||
|
@ -2,6 +2,8 @@
|
||||
namespace common\models;
|
||||
|
||||
use common\components\SkinSystem\Api as SkinSystemApi;
|
||||
use DateInterval;
|
||||
use DateTime;
|
||||
|
||||
class Textures {
|
||||
|
||||
@ -38,7 +40,7 @@ class Textures {
|
||||
|
||||
public function getTexturesValue($encrypted = true) {
|
||||
$array = [
|
||||
'timestamp' => time() + 60 * 60 * 24 * 2,
|
||||
'timestamp' => (new DateTime())->add(new DateInterval('P2D'))->getTimestamp(),
|
||||
'profileId' => str_replace('-', '', $this->account->uuid),
|
||||
'profileName' => $this->account->username,
|
||||
'textures' => $this->getTextures(),
|
||||
@ -51,7 +53,7 @@ class Textures {
|
||||
if (!$encrypted) {
|
||||
return $array;
|
||||
} else {
|
||||
return $this->encrypt($array);
|
||||
return static::encrypt($array);
|
||||
}
|
||||
}
|
||||
|
||||
|
64
common/validators/EmailValidator.php
Normal file
64
common/validators/EmailValidator.php
Normal file
@ -0,0 +1,64 @@
|
||||
<?php
|
||||
namespace common\validators;
|
||||
|
||||
use common\helpers\Error as E;
|
||||
use common\models\Account;
|
||||
use Ely\Yii2\TempmailValidator;
|
||||
use yii\base\Model;
|
||||
use yii\db\QueryInterface;
|
||||
use yii\validators;
|
||||
use yii\validators\Validator;
|
||||
|
||||
class EmailValidator extends Validator {
|
||||
|
||||
/**
|
||||
* @var \Closure функция должна возвращать id аккаунта, относительно которого проводится
|
||||
* текущая валидация. Позволяет пропустить проверку email для текущего аккаунта.
|
||||
*/
|
||||
public $accountCallback;
|
||||
|
||||
public $skipOnEmpty = false;
|
||||
|
||||
public function validateAttribute($model, $attribute) {
|
||||
$filter = new validators\FilterValidator(['filter' => 'trim']);
|
||||
|
||||
$required = new validators\RequiredValidator();
|
||||
$required->message = E::EMAIL_REQUIRED;
|
||||
|
||||
$length = new validators\StringValidator();
|
||||
$length->max = 255;
|
||||
$length->tooLong = E::EMAIL_TOO_LONG;
|
||||
|
||||
$email = new validators\EmailValidator();
|
||||
$email->checkDNS = true;
|
||||
$email->enableIDN = true;
|
||||
$email->message = E::EMAIL_INVALID;
|
||||
|
||||
$tempmail = new TempmailValidator();
|
||||
$tempmail->message = E::EMAIL_IS_TEMPMAIL;
|
||||
|
||||
$unique = new validators\UniqueValidator();
|
||||
$unique->message = E::EMAIL_NOT_AVAILABLE;
|
||||
$unique->targetClass = Account::class;
|
||||
$unique->targetAttribute = 'email';
|
||||
if ($this->accountCallback !== null) {
|
||||
$unique->filter = function(QueryInterface $query) {
|
||||
$query->andWhere(['NOT', ['id' => ($this->accountCallback)()]]);
|
||||
};
|
||||
}
|
||||
|
||||
$this->executeValidation($filter, $model, $attribute) &&
|
||||
$this->executeValidation($required, $model, $attribute) &&
|
||||
$this->executeValidation($length, $model, $attribute) &&
|
||||
$this->executeValidation($email, $model, $attribute) &&
|
||||
$this->executeValidation($tempmail, $model, $attribute) &&
|
||||
$this->executeValidation($unique, $model, $attribute);
|
||||
}
|
||||
|
||||
protected function executeValidation(Validator $validator, Model $model, string $attribute) {
|
||||
$validator->validateAttribute($model, $attribute);
|
||||
|
||||
return !$model->hasErrors($attribute);
|
||||
}
|
||||
|
||||
}
|
@ -7,7 +7,7 @@ use yii\validators\StringValidator;
|
||||
/**
|
||||
* Класс должен реализовывать в себе все критерии валидации пароля пользователя
|
||||
*/
|
||||
class PasswordValidate extends StringValidator {
|
||||
class PasswordValidator extends StringValidator {
|
||||
|
||||
public $min = 8;
|
||||
|
59
common/validators/UsernameValidator.php
Normal file
59
common/validators/UsernameValidator.php
Normal file
@ -0,0 +1,59 @@
|
||||
<?php
|
||||
namespace common\validators;
|
||||
|
||||
use common\helpers\Error as E;
|
||||
use common\models\Account;
|
||||
use yii\base\Model;
|
||||
use yii\db\QueryInterface;
|
||||
use yii\validators;
|
||||
use yii\validators\Validator;
|
||||
|
||||
class UsernameValidator extends Validator {
|
||||
|
||||
/**
|
||||
* @var \Closure функция должна возвращать id аккаунта, относительно которого проводится
|
||||
* текущая валидация. Позволяет пропустить проверку ника для текущего аккаунта.
|
||||
*/
|
||||
public $accountCallback;
|
||||
|
||||
public $skipOnEmpty = false;
|
||||
|
||||
public function validateAttribute($model, $attribute) {
|
||||
$filter = new validators\FilterValidator(['filter' => 'trim']);
|
||||
|
||||
$required = new validators\RequiredValidator();
|
||||
$required->message = E::USERNAME_REQUIRED;
|
||||
|
||||
$length = new validators\StringValidator();
|
||||
$length->min = 3;
|
||||
$length->max = 21;
|
||||
$length->tooShort = E::USERNAME_TOO_SHORT;
|
||||
$length->tooLong = E::USERNAME_TOO_LONG;
|
||||
|
||||
$pattern = new validators\RegularExpressionValidator(['pattern' => '/^[\p{L}\d-_\.!$%^&*()\[\]:;]+$/u']);
|
||||
$pattern->message = E::USERNAME_INVALID;
|
||||
|
||||
$unique = new validators\UniqueValidator();
|
||||
$unique->message = E::USERNAME_NOT_AVAILABLE;
|
||||
$unique->targetClass = Account::class;
|
||||
$unique->targetAttribute = 'username';
|
||||
if ($this->accountCallback !== null) {
|
||||
$unique->filter = function(QueryInterface $query) {
|
||||
$query->andWhere(['NOT', ['id' => ($this->accountCallback)()]]);
|
||||
};
|
||||
}
|
||||
|
||||
$this->executeValidation($filter, $model, $attribute) &&
|
||||
$this->executeValidation($required, $model, $attribute) &&
|
||||
$this->executeValidation($length, $model, $attribute) &&
|
||||
$this->executeValidation($pattern, $model, $attribute) &&
|
||||
$this->executeValidation($unique, $model, $attribute);
|
||||
}
|
||||
|
||||
protected function executeValidation(Validator $validator, Model $model, string $attribute) {
|
||||
$validator->validateAttribute($model, $attribute);
|
||||
|
||||
return !$model->hasErrors($attribute);
|
||||
}
|
||||
|
||||
}
|
@ -7,6 +7,8 @@ use yii\validators\Validator;
|
||||
|
||||
class UuidValidator extends Validator {
|
||||
|
||||
public $allowNil = true;
|
||||
|
||||
public $skipOnEmpty = false;
|
||||
|
||||
public $message = '{attribute} must be valid uuid';
|
||||
@ -18,6 +20,10 @@ class UuidValidator extends Validator {
|
||||
} catch (InvalidArgumentException $e) {
|
||||
$this->addError($model, $attribute, $this->message, []);
|
||||
}
|
||||
|
||||
if (isset($uuid) && $this->allowNil === false && $uuid === Uuid::NIL) {
|
||||
$this->addError($model, $attribute, $this->message, []);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -24,13 +24,12 @@
|
||||
"php-amqplib/php-amqplib": "^2.6.2",
|
||||
"ely/yii2-tempmail-validator": "~1.0.0",
|
||||
"emarref/jwt": "~1.0.3",
|
||||
"ely/amqp-controller": "^0.1.2",
|
||||
"ely/amqp-controller": "dev-master#d7f8cdbc66c45e477c9c7d5d509bc0c1b11fd3ec",
|
||||
"ely/email-renderer": "dev-master#38a148cd5081147acc31125ddc49966b149f65cf"
|
||||
},
|
||||
"require-dev": {
|
||||
"yiisoft/yii2-codeception": "*",
|
||||
"yiisoft/yii2-debug": "*",
|
||||
"yiisoft/yii2-gii": "*",
|
||||
"yiisoft/yii2-faker": "*",
|
||||
"flow/jsonpath": "^0.3.1",
|
||||
"codeception/codeception": "~2.2.4",
|
||||
|
@ -3,10 +3,9 @@ namespace console\controllers;
|
||||
|
||||
use common\components\Mojang\Api as MojangApi;
|
||||
use common\components\Mojang\exceptions\NoContentException;
|
||||
use common\components\RabbitMQ\Component as RabbitMQComponent;
|
||||
use common\models\amqp\UsernameChanged;
|
||||
use common\models\MojangUsername;
|
||||
use console\controllers\base\AmqpController;
|
||||
use Ely\Amqp\Builder\Configurator;
|
||||
use GuzzleHttp\Exception\RequestException;
|
||||
|
||||
class AccountQueueController extends AmqpController {
|
||||
@ -15,19 +14,10 @@ class AccountQueueController extends AmqpController {
|
||||
return 'events';
|
||||
}
|
||||
|
||||
public function getQueueName() {
|
||||
return 'accounts-events';
|
||||
}
|
||||
|
||||
protected function getExchangeDeclareArgs() {
|
||||
return array_replace(parent::getExchangeDeclareArgs(), [
|
||||
1 => RabbitMQComponent::TYPE_TOPIC, // type -> topic
|
||||
3 => true, // durable -> true
|
||||
]);
|
||||
}
|
||||
|
||||
protected function getQueueBindArgs($exchangeName, $queueName) {
|
||||
return [$queueName, $exchangeName, 'accounts.#'];
|
||||
public function configure(Configurator $configurator) {
|
||||
$configurator->exchange->topic()->durable();
|
||||
$configurator->queue->name('accounts-accounts-events')->durable();
|
||||
$configurator->bind->routingKey('accounts.username-changed');
|
||||
}
|
||||
|
||||
public function getRoutesMap() {
|
||||
@ -37,7 +27,7 @@ class AccountQueueController extends AmqpController {
|
||||
}
|
||||
|
||||
public function routeUsernameChanged(UsernameChanged $body) {
|
||||
$mojangApi = new MojangApi();
|
||||
$mojangApi = $this->createMojangApi();
|
||||
try {
|
||||
$response = $mojangApi->usernameToUUID($body->newUsername);
|
||||
} catch (NoContentException $e) {
|
||||
@ -68,4 +58,11 @@ class AccountQueueController extends AmqpController {
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return MojangApi
|
||||
*/
|
||||
protected function createMojangApi() : MojangApi {
|
||||
return new MojangApi();
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -1,5 +1,5 @@
|
||||
<?php
|
||||
namespace console\controllers\base;
|
||||
namespace console\controllers;
|
||||
|
||||
use Ely\Amqp\ControllerTrait;
|
||||
use Yii;
|
36
console/migrations/m161030_013122_ely_by_admin_app.php
Normal file
36
console/migrations/m161030_013122_ely_by_admin_app.php
Normal file
@ -0,0 +1,36 @@
|
||||
<?php
|
||||
|
||||
use console\db\Migration;
|
||||
|
||||
class m161030_013122_ely_by_admin_app extends Migration {
|
||||
|
||||
const APP_NAME = 'ely_admin';
|
||||
|
||||
public function safeUp() {
|
||||
$exists = $this->db->createCommand('
|
||||
SELECT COUNT(*)
|
||||
FROM {{%oauth_clients}}
|
||||
WHERE id = :app_name
|
||||
LIMIT 1
|
||||
', [
|
||||
'app_name' => self::APP_NAME,
|
||||
])->queryScalar();
|
||||
|
||||
if (!$exists) {
|
||||
$this->insert('{{%oauth_clients}}', [
|
||||
'id' => self::APP_NAME,
|
||||
'secret' => 'change_this_on_production',
|
||||
'name' => 'Admin Ely.by',
|
||||
'description' => '',
|
||||
'redirect_uri' => 'http://admin.ely.by/authorization/oauth',
|
||||
'is_trusted' => 1,
|
||||
'created_at' => time(),
|
||||
]);
|
||||
}
|
||||
}
|
||||
|
||||
public function safeDown() {
|
||||
$this->delete('{{%oauth_clients}}', ['id' => self::APP_NAME]);
|
||||
}
|
||||
|
||||
}
|
15
console/migrations/m161104_150634_accounts_uuid_index.php
Normal file
15
console/migrations/m161104_150634_accounts_uuid_index.php
Normal file
@ -0,0 +1,15 @@
|
||||
<?php
|
||||
|
||||
use console\db\Migration;
|
||||
|
||||
class m161104_150634_accounts_uuid_index extends Migration {
|
||||
|
||||
public function safeUp() {
|
||||
$this->createIndex('uuid', '{{%accounts}}', 'uuid', true);
|
||||
}
|
||||
|
||||
public function safeDown() {
|
||||
$this->dropColumn('{{%accounts}}', 'uuid');
|
||||
}
|
||||
|
||||
}
|
@ -1,7 +1,7 @@
|
||||
version: '2'
|
||||
services:
|
||||
app:
|
||||
build: .
|
||||
image: registry.ely.by/elyby/accounts:latest
|
||||
depends_on:
|
||||
- db
|
||||
- redis
|
||||
|
@ -30,9 +30,9 @@ fi
|
||||
|
||||
if [ "$YII_ENV" != "test" ]
|
||||
then
|
||||
wait-for-it db:3306 -- "php /var/www/html/yii migrate/up --interactive=0"
|
||||
wait-for-it db:3306 -s -- "php /var/www/html/yii migrate/up --interactive=0"
|
||||
else
|
||||
wait-for-it testdb:3306 -- "php /var/www/html/tests/codeception/bin/yii migrate/up --interactive=0"
|
||||
wait-for-it testdb:3306 -s -- "php /var/www/html/tests/codeception/bin/yii migrate/up --interactive=0"
|
||||
fi
|
||||
|
||||
exec "$@"
|
||||
|
@ -12,6 +12,7 @@ modules:
|
||||
config:
|
||||
Yii2:
|
||||
configFile: '../config/api/functional.php'
|
||||
cleanup: true
|
||||
Redis:
|
||||
host: testredis
|
||||
port: 6379
|
||||
|
@ -1,7 +1,6 @@
|
||||
<?php
|
||||
namespace tests\codeception\api\functional;
|
||||
|
||||
use Codeception\Specify;
|
||||
use tests\codeception\api\_pages\AccountsRoute;
|
||||
use tests\codeception\api\FunctionalTester;
|
||||
|
||||
|
@ -26,7 +26,6 @@ class AccountsCurrentCest {
|
||||
'username' => 'Admin',
|
||||
'email' => 'admin@ely.by',
|
||||
'lang' => 'en',
|
||||
'shouldChangePassword' => false,
|
||||
'isActive' => true,
|
||||
'hasMojangUsernameCollision' => false,
|
||||
'shouldAcceptRules' => false,
|
||||
|
@ -1,7 +1,6 @@
|
||||
<?php
|
||||
namespace tests\codeception\api\functional;
|
||||
|
||||
use Codeception\Specify;
|
||||
use common\models\Account;
|
||||
use tests\codeception\api\_pages\SignupRoute;
|
||||
use tests\codeception\api\FunctionalTester;
|
||||
@ -216,6 +215,40 @@ class RegisterCest {
|
||||
'rulesAgreement' => true,
|
||||
'lang' => 'ru',
|
||||
]);
|
||||
$this->assertSuccessRegistration($I);
|
||||
}
|
||||
|
||||
public function testUserCorrectRegistrationWithReassignUsername(FunctionalTester $I) {
|
||||
$route = new SignupRoute($I);
|
||||
|
||||
$I->wantTo('ensure that signup allow reassign not finished registration username');
|
||||
$route->register([
|
||||
'username' => 'howe.garnett',
|
||||
'email' => 'custom-email@gmail.com',
|
||||
'password' => 'some_password',
|
||||
'rePassword' => 'some_password',
|
||||
'rulesAgreement' => true,
|
||||
'lang' => 'ru',
|
||||
]);
|
||||
$this->assertSuccessRegistration($I);
|
||||
}
|
||||
|
||||
public function testUserCorrectRegistrationWithReassignEmail(FunctionalTester $I) {
|
||||
$route = new SignupRoute($I);
|
||||
|
||||
$I->wantTo('ensure that signup allow reassign not finished registration email');
|
||||
$route->register([
|
||||
'username' => 'CustomUsername',
|
||||
'email' => 'achristiansen@gmail.com',
|
||||
'password' => 'some_password',
|
||||
'rePassword' => 'some_password',
|
||||
'rulesAgreement' => true,
|
||||
'lang' => 'ru',
|
||||
]);
|
||||
$this->assertSuccessRegistration($I);
|
||||
}
|
||||
|
||||
private function assertSuccessRegistration(FunctionalTester $I) {
|
||||
$I->canSeeResponseCodeIs(200);
|
||||
$I->canSeeResponseIsJson();
|
||||
$I->canSeeResponseContainsJson(['success' => true]);
|
||||
|
@ -1,4 +1 @@
|
||||
<?php
|
||||
new yii\web\Application(require __DIR__ . '/../../config/api/functional.php');
|
||||
|
||||
\Codeception\Util\Autoload::registerSuffix('Steps', __DIR__ . DIRECTORY_SEPARATOR);
|
||||
|
@ -111,6 +111,21 @@ class JoinCest {
|
||||
]);
|
||||
}
|
||||
|
||||
public function joinWithNilUuids(FunctionalTester $I) {
|
||||
$I->wantTo('join to some server with nil accessToken and selectedProfile');
|
||||
$this->route->join([
|
||||
'accessToken' => '00000000-0000-0000-0000-000000000000',
|
||||
'selectedProfile' => 'df936908-b2e1-544d-96f8-2977ec213022',
|
||||
'serverId' => Uuid::uuid(),
|
||||
]);
|
||||
$I->canSeeResponseCodeIs(400);
|
||||
$I->canSeeResponseIsJson();
|
||||
$I->canSeeResponseContainsJson([
|
||||
'error' => 'IllegalArgumentException',
|
||||
'errorMessage' => 'credentials can not be null.',
|
||||
]);
|
||||
}
|
||||
|
||||
private function expectSuccessResponse(FunctionalTester $I) {
|
||||
$I->seeResponseCodeIs(200);
|
||||
$I->seeResponseIsJson();
|
||||
|
@ -84,6 +84,17 @@ class JoinLegacyCest {
|
||||
$I->canSeeResponseContains('Ely.by authorization required');
|
||||
}
|
||||
|
||||
public function joinWithNilUuids(FunctionalTester $I) {
|
||||
$I->wantTo('join to some server by legacy protocol with nil accessToken and selectedProfile');
|
||||
$this->route->joinLegacy([
|
||||
'sessionId' => 'token:00000000-0000-0000-0000-000000000000:00000000-0000-0000-0000-000000000000',
|
||||
'user' => 'SomeUser',
|
||||
'serverId' => Uuid::uuid(),
|
||||
]);
|
||||
$I->canSeeResponseCodeIs(400);
|
||||
$I->canSeeResponseContains('credentials can not be null.');
|
||||
}
|
||||
|
||||
private function expectSuccessResponse(FunctionalTester $I) {
|
||||
$I->seeResponseCodeIs(200);
|
||||
$I->canSeeResponseEquals('OK');
|
||||
|
@ -1 +1,8 @@
|
||||
class_name: UnitTester
|
||||
modules:
|
||||
enabled:
|
||||
- Yii2:
|
||||
part: [orm, email, fixtures]
|
||||
config:
|
||||
Yii2:
|
||||
configFile: '../config/api/unit.php'
|
||||
|
@ -1,9 +0,0 @@
|
||||
<?php
|
||||
namespace tests\codeception\api\unit;
|
||||
|
||||
|
||||
class DbTestCase extends \yii\codeception\DbTestCase {
|
||||
|
||||
public $appConfig = '@tests/codeception/config/api/unit.php';
|
||||
|
||||
}
|
@ -1,9 +1,22 @@
|
||||
<?php
|
||||
namespace tests\codeception\api\unit;
|
||||
|
||||
class TestCase extends \Codeception\Test\Unit {
|
||||
|
||||
class TestCase extends \yii\codeception\TestCase {
|
||||
/**
|
||||
* @var \tests\codeception\api\UnitTester
|
||||
*/
|
||||
protected $tester;
|
||||
|
||||
public $appConfig = '@tests/codeception/config/api/unit.php';
|
||||
/**
|
||||
* Список фикстур, что будут загружены перед тестом, но после зачистки базы данных
|
||||
*
|
||||
* @url http://codeception.com/docs/modules/Yii2#fixtures
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function _fixtures() {
|
||||
return [];
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -11,7 +11,7 @@ use Emarref\Jwt\Algorithm\AlgorithmInterface;
|
||||
use Emarref\Jwt\Claim\ClaimInterface;
|
||||
use Emarref\Jwt\Claim\Expiration;
|
||||
use Emarref\Jwt\Token;
|
||||
use tests\codeception\api\unit\DbTestCase;
|
||||
use tests\codeception\api\unit\TestCase;
|
||||
use tests\codeception\common\_support\ProtectedCaller;
|
||||
use tests\codeception\common\fixtures\AccountFixture;
|
||||
use tests\codeception\common\fixtures\AccountSessionFixture;
|
||||
@ -19,11 +19,7 @@ use Yii;
|
||||
use yii\web\HeaderCollection;
|
||||
use yii\web\Request;
|
||||
|
||||
/**
|
||||
* @property AccountFixture $accounts
|
||||
* @property AccountSessionFixture $sessions
|
||||
*/
|
||||
class ComponentTest extends DbTestCase {
|
||||
class ComponentTest extends TestCase {
|
||||
use Specify;
|
||||
use ProtectedCaller;
|
||||
|
||||
@ -37,7 +33,7 @@ class ComponentTest extends DbTestCase {
|
||||
$this->component = new Component($this->getComponentArguments());
|
||||
}
|
||||
|
||||
public function fixtures() {
|
||||
public function _fixtures() {
|
||||
return [
|
||||
'accounts' => AccountFixture::class,
|
||||
'sessions' => AccountSessionFixture::class,
|
||||
@ -62,7 +58,7 @@ class ComponentTest extends DbTestCase {
|
||||
|
||||
$this->specify('success get LoginResult object with session value if rememberMe is true', function() {
|
||||
/** @var AccountIdentity $account */
|
||||
$account = AccountIdentity::findOne($this->accounts['admin']['id']);
|
||||
$account = AccountIdentity::findOne($this->tester->grabFixture('accounts', 'admin')['id']);
|
||||
$result = $this->component->login($account, true);
|
||||
expect($result)->isInstanceOf(LoginResult::class);
|
||||
expect($result->getSession())->isInstanceOf(AccountSession::class);
|
||||
@ -82,7 +78,7 @@ class ComponentTest extends DbTestCase {
|
||||
$userIP = '192.168.0.1';
|
||||
$this->mockRequest($userIP);
|
||||
/** @var AccountSession $session */
|
||||
$session = AccountSession::findOne($this->sessions['admin']['id']);
|
||||
$session = AccountSession::findOne($this->tester->grabFixture('sessions', 'admin')['id']);
|
||||
$callTime = time();
|
||||
$result = $this->component->renew($session);
|
||||
expect($result)->isInstanceOf(RenewResult::class);
|
||||
@ -108,7 +104,7 @@ class ComponentTest extends DbTestCase {
|
||||
public function testGetActiveSession() {
|
||||
$this->specify('get used account session', function() {
|
||||
/** @var AccountIdentity $identity */
|
||||
$identity = AccountIdentity::findOne($this->accounts['admin']['id']);
|
||||
$identity = AccountIdentity::findOne($this->tester->grabFixture('accounts', 'admin')['id']);
|
||||
$result = $this->component->login($identity, true);
|
||||
$this->component->logout();
|
||||
|
||||
@ -184,6 +180,7 @@ class ComponentTest extends DbTestCase {
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $userIP
|
||||
* @return \PHPUnit_Framework_MockObject_MockObject
|
||||
*/
|
||||
private function mockRequest($userIP = '127.0.0.1') {
|
||||
|
@ -7,8 +7,8 @@ use Codeception\Specify;
|
||||
use common\models\Account;
|
||||
use tests\codeception\api\unit\TestCase;
|
||||
use tests\codeception\common\_support\ProtectedCaller;
|
||||
use const common\LATEST_RULES_VERSION;
|
||||
use yii\base\Action;
|
||||
use const common\LATEST_RULES_VERSION;
|
||||
|
||||
class ActiveUserRuleTest extends TestCase {
|
||||
use Specify;
|
||||
|
@ -7,7 +7,7 @@ use Emarref\Jwt\Claim;
|
||||
use Emarref\Jwt\Encryption\Factory as EncryptionFactory;
|
||||
use Emarref\Jwt\Jwt;
|
||||
use Emarref\Jwt\Token;
|
||||
use tests\codeception\api\unit\DbTestCase;
|
||||
use tests\codeception\api\unit\TestCase;
|
||||
use tests\codeception\common\_support\ProtectedCaller;
|
||||
use tests\codeception\common\fixtures\AccountFixture;
|
||||
use Yii;
|
||||
@ -16,11 +16,11 @@ use yii\web\IdentityInterface;
|
||||
/**
|
||||
* @property AccountIdentity $accounts
|
||||
*/
|
||||
class AccountIdentityTest extends DbTestCase {
|
||||
class AccountIdentityTest extends TestCase {
|
||||
use Specify;
|
||||
use ProtectedCaller;
|
||||
|
||||
public function fixtures() {
|
||||
public function _fixtures() {
|
||||
return [
|
||||
'accounts' => AccountFixture::class,
|
||||
];
|
||||
@ -29,7 +29,7 @@ class AccountIdentityTest extends DbTestCase {
|
||||
public function testFindIdentityByAccessToken() {
|
||||
$identity = AccountIdentity::findIdentityByAccessToken($this->generateToken());
|
||||
$this->assertInstanceOf(IdentityInterface::class, $identity);
|
||||
$this->assertEquals($this->accounts['admin']['id'], $identity->getId());
|
||||
$this->assertEquals($this->tester->grabFixture('accounts', 'admin')['id'], $identity->getId());
|
||||
}
|
||||
|
||||
/**
|
||||
@ -42,7 +42,7 @@ class AccountIdentityTest extends DbTestCase {
|
||||
$token->addClaim(new Claim\Issuer('http://localhost'));
|
||||
$token->addClaim(new Claim\IssuedAt(1464593193));
|
||||
$token->addClaim(new Claim\Expiration(1464596793));
|
||||
$token->addClaim(new Claim\JwtId($this->accounts['admin']['id']));
|
||||
$token->addClaim(new Claim\JwtId($this->tester->grabFixture('accounts', 'admin')['id']));
|
||||
$expiredToken = (new Jwt())->serialize($token, EncryptionFactory::create(Yii::$app->user->getAlgorithm()));
|
||||
|
||||
AccountIdentity::findIdentityByAccessToken($expiredToken);
|
||||
@ -60,7 +60,7 @@ class AccountIdentityTest extends DbTestCase {
|
||||
/** @var \api\components\User\Component $component */
|
||||
$component = Yii::$app->user;
|
||||
/** @var AccountIdentity $account */
|
||||
$account = AccountIdentity::findOne($this->accounts['admin']['id']);
|
||||
$account = AccountIdentity::findOne($this->tester->grabFixture('accounts', 'admin')['id']);
|
||||
|
||||
$token = $this->callProtected($component, 'createToken', $account);
|
||||
|
||||
|
@ -2,76 +2,48 @@
|
||||
namespace codeception\api\unit\models;
|
||||
|
||||
use api\models\FeedbackForm;
|
||||
use Codeception\Specify;
|
||||
use common\models\Account;
|
||||
use tests\codeception\api\unit\TestCase;
|
||||
use Yii;
|
||||
use yii\swiftmailer\Message;
|
||||
|
||||
class FeedbackFormTest extends TestCase {
|
||||
use Specify;
|
||||
|
||||
const FILE_NAME = 'testing_message.eml';
|
||||
|
||||
public function setUp() {
|
||||
parent::setUp();
|
||||
/** @var \yii\swiftmailer\Mailer $mailer */
|
||||
$mailer = Yii::$app->mailer;
|
||||
$mailer->fileTransportCallback = function() {
|
||||
return self::FILE_NAME;
|
||||
};
|
||||
}
|
||||
|
||||
protected function tearDown() {
|
||||
if (file_exists($this->getMessageFile())) {
|
||||
unlink($this->getMessageFile());
|
||||
}
|
||||
|
||||
parent::tearDown();
|
||||
}
|
||||
|
||||
public function testSendMessage() {
|
||||
$this->specify('send email', function() {
|
||||
$model = new FeedbackForm([
|
||||
$model = new FeedbackForm([
|
||||
'subject' => 'Тема обращения',
|
||||
'email' => 'erickskrauch@ely.by',
|
||||
'message' => 'Привет мир!',
|
||||
]);
|
||||
$this->assertTrue($model->sendMessage());
|
||||
$this->tester->seeEmailIsSent(1, 'message file exists');
|
||||
}
|
||||
|
||||
public function testSendMessageWithEmail() {
|
||||
/** @var FeedbackForm|\PHPUnit_Framework_MockObject_MockObject $model */
|
||||
$model = $this->getMockBuilder(FeedbackForm::class)
|
||||
->setMethods(['getAccount'])
|
||||
->setConstructorArgs([[
|
||||
'subject' => 'Тема обращения',
|
||||
'email' => 'erickskrauch@ely.by',
|
||||
'message' => 'Привет мир!',
|
||||
]);
|
||||
expect($model->sendMessage())->true();
|
||||
expect_file('message file exists', $this->getMessageFile())->exists();
|
||||
});
|
||||
]])
|
||||
->getMock();
|
||||
|
||||
$this->specify('send email with user info', function() {
|
||||
/** @var FeedbackForm|\PHPUnit_Framework_MockObject_MockObject $model */
|
||||
$model = $this->getMockBuilder(FeedbackForm::class)
|
||||
->setMethods(['getAccount'])
|
||||
->setConstructorArgs([[
|
||||
'subject' => 'Тема обращения',
|
||||
'email' => 'erickskrauch@ely.by',
|
||||
'message' => 'Привет мир!',
|
||||
]])
|
||||
->getMock();
|
||||
|
||||
$model
|
||||
->expects($this->any())
|
||||
->method('getAccount')
|
||||
->will($this->returnValue(new Account([
|
||||
'id' => '123',
|
||||
'username' => 'Erick',
|
||||
'email' => 'find-this@email.net',
|
||||
'created_at' => time() - 86400,
|
||||
])));
|
||||
expect($model->sendMessage())->true();
|
||||
expect_file('message file exists', $this->getMessageFile())->exists();
|
||||
$data = file_get_contents($this->getMessageFile());
|
||||
expect(strpos($data, 'find-this@email.net'))->notEquals(false);
|
||||
});
|
||||
}
|
||||
|
||||
private function getMessageFile() {
|
||||
/** @var \yii\swiftmailer\Mailer $mailer */
|
||||
$mailer = Yii::$app->mailer;
|
||||
|
||||
return Yii::getAlias($mailer->fileTransportPath) . '/' . self::FILE_NAME;
|
||||
$model
|
||||
->expects($this->any())
|
||||
->method('getAccount')
|
||||
->will($this->returnValue(new Account([
|
||||
'id' => '123',
|
||||
'username' => 'Erick',
|
||||
'email' => 'find-this@email.net',
|
||||
'created_at' => time() - 86400,
|
||||
])));
|
||||
$this->assertTrue($model->sendMessage());
|
||||
/** @var Message $message */
|
||||
$message = $this->tester->grabLastSentEmail();
|
||||
$this->assertInstanceOf(Message::class, $message);
|
||||
$data = (string)$message;
|
||||
$this->assertContains('find-this@email.net', $data);
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -3,45 +3,37 @@ namespace tests\codeception\api\models\authentication;
|
||||
|
||||
use api\components\User\LoginResult;
|
||||
use api\models\authentication\ConfirmEmailForm;
|
||||
use Codeception\Specify;
|
||||
use common\models\Account;
|
||||
use common\models\AccountSession;
|
||||
use common\models\EmailActivation;
|
||||
use tests\codeception\api\unit\DbTestCase;
|
||||
use tests\codeception\api\unit\TestCase;
|
||||
use tests\codeception\common\fixtures\EmailActivationFixture;
|
||||
use Yii;
|
||||
|
||||
/**
|
||||
* @property EmailActivationFixture $emailActivations
|
||||
*/
|
||||
class ConfirmEmailFormTest extends DbTestCase {
|
||||
use Specify;
|
||||
class ConfirmEmailFormTest extends TestCase {
|
||||
|
||||
public function fixtures() {
|
||||
public function _fixtures() {
|
||||
return [
|
||||
'emailActivations' => EmailActivationFixture::class,
|
||||
];
|
||||
}
|
||||
|
||||
protected function createModel($key) {
|
||||
public function testConfirm() {
|
||||
$fixture = $this->tester->grabFixture('emailActivations', 'freshRegistrationConfirmation');
|
||||
$model = $this->createModel($fixture['key']);
|
||||
$result = $model->confirm();
|
||||
$this->assertInstanceOf(LoginResult::class, $result);
|
||||
$this->assertInstanceOf(AccountSession::class, $result->getSession(), 'session was generated');
|
||||
$activationExists = EmailActivation::find()->andWhere(['key' => $fixture['key']])->exists();
|
||||
$this->assertFalse($activationExists, 'email activation key is not exist');
|
||||
/** @var Account $user */
|
||||
$user = Account::findOne($fixture['account_id']);
|
||||
$this->assertEquals(Account::STATUS_ACTIVE, $user->status, 'user status changed to active');
|
||||
}
|
||||
|
||||
private function createModel($key) {
|
||||
return new ConfirmEmailForm([
|
||||
'key' => $key,
|
||||
]);
|
||||
}
|
||||
|
||||
public function testConfirm() {
|
||||
$fixture = $this->emailActivations['freshRegistrationConfirmation'];
|
||||
$model = $this->createModel($fixture['key']);
|
||||
$this->specify('expect true result', function() use ($model, $fixture) {
|
||||
$result = $model->confirm();
|
||||
expect($result)->isInstanceOf(LoginResult::class);
|
||||
expect('session was generated', $result->getSession())->isInstanceOf(AccountSession::class);
|
||||
$activationExists = EmailActivation::find()->andWhere(['key' => $fixture['key']])->exists();
|
||||
expect('email activation key is not exist', $activationExists)->false();
|
||||
/** @var Account $user */
|
||||
$user = Account::findOne($fixture['account_id']);
|
||||
expect('user status changed to active', $user->status)->equals(Account::STATUS_ACTIVE);
|
||||
});
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -4,41 +4,16 @@ namespace codeception\api\unit\models\authentication;
|
||||
use api\models\authentication\ForgotPasswordForm;
|
||||
use Codeception\Specify;
|
||||
use common\models\EmailActivation;
|
||||
use tests\codeception\api\unit\DbTestCase;
|
||||
use tests\codeception\api\unit\TestCase;
|
||||
use tests\codeception\common\fixtures\AccountFixture;
|
||||
use tests\codeception\common\fixtures\EmailActivationFixture;
|
||||
use Yii;
|
||||
|
||||
/**
|
||||
* @property AccountFixture $accounts
|
||||
* @property EmailActivationFixture $emailActivations
|
||||
*/
|
||||
class ForgotPasswordFormTest extends DbTestCase {
|
||||
class ForgotPasswordFormTest extends TestCase {
|
||||
use Specify;
|
||||
|
||||
protected function setUp() {
|
||||
parent::setUp();
|
||||
/** @var \yii\swiftmailer\Mailer $mailer */
|
||||
$mailer = Yii::$app->mailer;
|
||||
$mailer->fileTransportCallback = function () {
|
||||
return 'testing_message.eml';
|
||||
};
|
||||
}
|
||||
|
||||
protected function tearDown() {
|
||||
if (file_exists($this->getMessageFile())) {
|
||||
unlink($this->getMessageFile());
|
||||
}
|
||||
|
||||
parent::tearDown();
|
||||
}
|
||||
|
||||
public function fixtures() {
|
||||
public function _fixtures() {
|
||||
return [
|
||||
'accounts' => [
|
||||
'class' => AccountFixture::class,
|
||||
'dataFile' => '@tests/codeception/common/fixtures/data/accounts.php',
|
||||
],
|
||||
'accounts' => AccountFixture::class,
|
||||
'emailActivations' => EmailActivationFixture::class,
|
||||
];
|
||||
}
|
||||
@ -51,7 +26,7 @@ class ForgotPasswordFormTest extends DbTestCase {
|
||||
});
|
||||
|
||||
$this->specify('empty errors if login is exists', function() {
|
||||
$model = new ForgotPasswordForm(['login' => $this->accounts['admin']['username']]);
|
||||
$model = new ForgotPasswordForm(['login' => $this->tester->grabFixture('accounts', 'admin')['username']]);
|
||||
$model->validateLogin('login');
|
||||
expect($model->getErrors('login'))->isEmpty();
|
||||
});
|
||||
@ -59,13 +34,17 @@ class ForgotPasswordFormTest extends DbTestCase {
|
||||
|
||||
public function testValidateActivity() {
|
||||
$this->specify('error.account_not_activated if account is not confirmed', function() {
|
||||
$model = new ForgotPasswordForm(['login' => $this->accounts['not-activated-account']['username']]);
|
||||
$model = new ForgotPasswordForm([
|
||||
'login' => $this->tester->grabFixture('accounts', 'not-activated-account')['username'],
|
||||
]);
|
||||
$model->validateActivity('login');
|
||||
expect($model->getErrors('login'))->equals(['error.account_not_activated']);
|
||||
});
|
||||
|
||||
$this->specify('empty errors if login is exists', function() {
|
||||
$model = new ForgotPasswordForm(['login' => $this->accounts['admin']['username']]);
|
||||
$model = new ForgotPasswordForm([
|
||||
'login' => $this->tester->grabFixture('accounts', 'admin')['username'],
|
||||
]);
|
||||
$model->validateLogin('login');
|
||||
expect($model->getErrors('login'))->isEmpty();
|
||||
});
|
||||
@ -74,8 +53,8 @@ class ForgotPasswordFormTest extends DbTestCase {
|
||||
public function testValidateFrequency() {
|
||||
$this->specify('error.account_not_activated if recently was message', function() {
|
||||
$model = $this->createModel([
|
||||
'login' => $this->accounts['admin']['username'],
|
||||
'key' => $this->emailActivations['freshPasswordRecovery']['key'],
|
||||
'login' => $this->tester->grabFixture('accounts', 'admin')['username'],
|
||||
'key' => $this->tester->grabFixture('emailActivations', 'freshPasswordRecovery')['key'],
|
||||
]);
|
||||
|
||||
$model->validateFrequency('login');
|
||||
@ -84,8 +63,8 @@ class ForgotPasswordFormTest extends DbTestCase {
|
||||
|
||||
$this->specify('empty errors if email was sent a long time ago', function() {
|
||||
$model = $this->createModel([
|
||||
'login' => $this->accounts['admin']['username'],
|
||||
'key' => $this->emailActivations['oldPasswordRecovery']['key'],
|
||||
'login' => $this->tester->grabFixture('accounts', 'admin')['username'],
|
||||
'key' => $this->tester->grabFixture('emailActivations', 'oldPasswordRecovery')['key'],
|
||||
]);
|
||||
|
||||
$model->validateFrequency('login');
|
||||
@ -94,7 +73,7 @@ class ForgotPasswordFormTest extends DbTestCase {
|
||||
|
||||
$this->specify('empty errors if previous confirmation model not founded', function() {
|
||||
$model = $this->createModel([
|
||||
'login' => $this->accounts['admin']['username'],
|
||||
'login' => $this->tester->grabFixture('accounts', 'admin')['username'],
|
||||
'key' => 'invalid-key',
|
||||
]);
|
||||
|
||||
@ -105,34 +84,28 @@ class ForgotPasswordFormTest extends DbTestCase {
|
||||
|
||||
public function testForgotPassword() {
|
||||
$this->specify('successfully send message with restore password key', function() {
|
||||
$model = new ForgotPasswordForm(['login' => $this->accounts['admin']['username']]);
|
||||
$model = new ForgotPasswordForm(['login' => $this->tester->grabFixture('accounts', 'admin')['username']]);
|
||||
expect($model->forgotPassword())->true();
|
||||
expect($model->getEmailActivation())->notNull();
|
||||
expect_file($this->getMessageFile())->exists();
|
||||
$this->tester->canSeeEmailIsSent(1);
|
||||
});
|
||||
}
|
||||
|
||||
public function testForgotPasswordResend() {
|
||||
$this->specify('successfully renew and send message with restore password key', function() {
|
||||
$fixture = $this->tester->grabFixture('accounts', 'account-with-expired-forgot-password-message');
|
||||
$model = new ForgotPasswordForm([
|
||||
'login' => $this->accounts['account-with-expired-forgot-password-message']['username'],
|
||||
'login' => $fixture['username'],
|
||||
]);
|
||||
$callTime = time();
|
||||
expect($model->forgotPassword())->true();
|
||||
$emailActivation = $model->getEmailActivation();
|
||||
expect($emailActivation)->notNull();
|
||||
expect($emailActivation->created_at)->greaterOrEquals($callTime);
|
||||
expect_file($this->getMessageFile())->exists();
|
||||
$this->tester->canSeeEmailIsSent(1);
|
||||
});
|
||||
}
|
||||
|
||||
private function getMessageFile() {
|
||||
/** @var \yii\swiftmailer\Mailer $mailer */
|
||||
$mailer = Yii::$app->mailer;
|
||||
|
||||
return Yii::getAlias($mailer->fileTransportPath) . '/testing_message.eml';
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array $params
|
||||
* @return ForgotPasswordForm
|
||||
|
@ -6,13 +6,10 @@ use api\models\AccountIdentity;
|
||||
use api\models\authentication\LoginForm;
|
||||
use Codeception\Specify;
|
||||
use common\models\Account;
|
||||
use tests\codeception\api\unit\DbTestCase;
|
||||
use tests\codeception\api\unit\TestCase;
|
||||
use tests\codeception\common\fixtures\AccountFixture;
|
||||
|
||||
/**
|
||||
* @property AccountFixture $accounts
|
||||
*/
|
||||
class LoginFormTest extends DbTestCase {
|
||||
class LoginFormTest extends TestCase {
|
||||
use Specify;
|
||||
|
||||
private $originalRemoteAddr;
|
||||
@ -28,7 +25,7 @@ class LoginFormTest extends DbTestCase {
|
||||
$_SERVER['REMOTE_ADDR'] = $this->originalRemoteAddr;
|
||||
}
|
||||
|
||||
public function fixtures() {
|
||||
public function _fixtures() {
|
||||
return [
|
||||
'accounts' => AccountFixture::class,
|
||||
];
|
||||
@ -119,7 +116,7 @@ class LoginFormTest extends DbTestCase {
|
||||
public function testLoginWithRehashing() {
|
||||
$this->specify('user, that login using account with old pass hash strategy should update it automatically', function () {
|
||||
$model = new LoginForm([
|
||||
'login' => $this->accounts['user-with-old-password-type']['username'],
|
||||
'login' => $this->tester->grabFixture('accounts', 'user-with-old-password-type')['username'],
|
||||
'password' => '12345678',
|
||||
]);
|
||||
expect($model->login())->isInstanceOf(LoginResult::class);
|
||||
|
@ -6,10 +6,10 @@ use api\models\AccountIdentity;
|
||||
use api\models\authentication\LogoutForm;
|
||||
use Codeception\Specify;
|
||||
use common\models\AccountSession;
|
||||
use tests\codeception\api\unit\DbTestCase;
|
||||
use tests\codeception\api\unit\TestCase;
|
||||
use Yii;
|
||||
|
||||
class LogoutFormTest extends DbTestCase {
|
||||
class LogoutFormTest extends TestCase {
|
||||
use Specify;
|
||||
|
||||
public function testValidateLogout() {
|
||||
|
@ -6,39 +6,32 @@ use api\models\authentication\RecoverPasswordForm;
|
||||
use Codeception\Specify;
|
||||
use common\models\Account;
|
||||
use common\models\EmailActivation;
|
||||
use tests\codeception\api\unit\DbTestCase;
|
||||
use tests\codeception\api\unit\TestCase;
|
||||
use tests\codeception\common\fixtures\EmailActivationFixture;
|
||||
use Yii;
|
||||
|
||||
/**
|
||||
* @property EmailActivationFixture $emailActivations
|
||||
*/
|
||||
class RecoverPasswordFormTest extends DbTestCase {
|
||||
class RecoverPasswordFormTest extends TestCase {
|
||||
use Specify;
|
||||
|
||||
public function fixtures() {
|
||||
public function _fixtures() {
|
||||
return [
|
||||
'emailActivations' => EmailActivationFixture::class,
|
||||
];
|
||||
}
|
||||
|
||||
public function testRecoverPassword() {
|
||||
$fixture = $this->emailActivations['freshPasswordRecovery'];
|
||||
$this->specify('change user account password by email confirmation key', function() use ($fixture) {
|
||||
$model = new RecoverPasswordForm([
|
||||
'key' => $fixture['key'],
|
||||
'newPassword' => '12345678',
|
||||
'newRePassword' => '12345678',
|
||||
]);
|
||||
$result = $model->recoverPassword();
|
||||
expect($result)->isInstanceOf(LoginResult::class);
|
||||
expect('session was not generated', $result->getSession())->null();
|
||||
$activationExists = EmailActivation::find()->andWhere(['key' => $fixture['key']])->exists();
|
||||
expect($activationExists)->false();
|
||||
/** @var Account $account */
|
||||
$account = Account::findOne($fixture['account_id']);
|
||||
expect($account->validatePassword('12345678'))->true();
|
||||
});
|
||||
$fixture = $this->tester->grabFixture('emailActivations', 'freshPasswordRecovery');
|
||||
$model = new RecoverPasswordForm([
|
||||
'key' => $fixture['key'],
|
||||
'newPassword' => '12345678',
|
||||
'newRePassword' => '12345678',
|
||||
]);
|
||||
$result = $model->recoverPassword();
|
||||
$this->assertInstanceOf(LoginResult::class, $result);
|
||||
$this->assertNull($result->getSession(), 'session was not generated');
|
||||
$this->assertFalse(EmailActivation::find()->andWhere(['key' => $fixture['key']])->exists());
|
||||
/** @var Account $account */
|
||||
$account = Account::findOne($fixture['account_id']);
|
||||
$this->assertTrue($account->validatePassword('12345678'));
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -5,16 +5,13 @@ use api\components\User\RenewResult;
|
||||
use api\models\authentication\RefreshTokenForm;
|
||||
use Codeception\Specify;
|
||||
use common\models\AccountSession;
|
||||
use tests\codeception\api\unit\DbTestCase;
|
||||
use tests\codeception\api\unit\TestCase;
|
||||
use tests\codeception\common\fixtures\AccountSessionFixture;
|
||||
|
||||
/**
|
||||
* @property AccountSessionFixture $sessions
|
||||
*/
|
||||
class RefreshTokenFormTest extends DbTestCase {
|
||||
class RefreshTokenFormTest extends TestCase {
|
||||
use Specify;
|
||||
|
||||
public function fixtures() {
|
||||
public function _fixtures() {
|
||||
return [
|
||||
'sessions' => AccountSessionFixture::class,
|
||||
];
|
||||
@ -45,11 +42,9 @@ class RefreshTokenFormTest extends DbTestCase {
|
||||
}
|
||||
|
||||
public function testRenew() {
|
||||
$this->specify('success renew token', function() {
|
||||
$model = new RefreshTokenForm();
|
||||
$model->refresh_token = $this->sessions['admin']['refresh_token'];
|
||||
expect($model->renew())->isInstanceOf(RenewResult::class);
|
||||
});
|
||||
$model = new RefreshTokenForm();
|
||||
$model->refresh_token = $this->tester->grabFixture('sessions', 'admin')['refresh_token'];
|
||||
$this->assertInstanceOf(RenewResult::class, $model->renew());
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -1,53 +1,34 @@
|
||||
<?php
|
||||
namespace tests\codeception\api\models\authentication;
|
||||
|
||||
use api\components\ReCaptcha\Validator;
|
||||
use api\components\ReCaptcha\Validator as ReCaptchaValidator;
|
||||
use api\models\authentication\RegistrationForm;
|
||||
use Codeception\Specify;
|
||||
use common\models\Account;
|
||||
use common\models\EmailActivation;
|
||||
use common\models\UsernameHistory;
|
||||
use tests\codeception\api\unit\DbTestCase;
|
||||
use tests\codeception\api\unit\TestCase;
|
||||
use tests\codeception\common\fixtures\AccountFixture;
|
||||
use Yii;
|
||||
use const common\LATEST_RULES_VERSION;
|
||||
use yii\web\Request;
|
||||
use const common\LATEST_RULES_VERSION;
|
||||
|
||||
/**
|
||||
* @property array $accounts
|
||||
*/
|
||||
class RegistrationFormTest extends DbTestCase {
|
||||
class RegistrationFormTest extends TestCase {
|
||||
use Specify;
|
||||
|
||||
public function setUp() {
|
||||
parent::setUp();
|
||||
/** @var \yii\swiftmailer\Mailer $mailer */
|
||||
$mailer = Yii::$app->mailer;
|
||||
$mailer->fileTransportCallback = function () {
|
||||
return 'testing_message.eml';
|
||||
};
|
||||
$this->mockRequest();
|
||||
Yii::$container->set(Validator::class, new class extends Validator {
|
||||
Yii::$container->set(ReCaptchaValidator::class, new class extends ReCaptchaValidator {
|
||||
public function validateValue($value) {
|
||||
return null;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
protected function tearDown() {
|
||||
if (file_exists($this->getMessageFile())) {
|
||||
unlink($this->getMessageFile());
|
||||
}
|
||||
|
||||
parent::tearDown();
|
||||
}
|
||||
|
||||
public function fixtures() {
|
||||
public function _fixtures() {
|
||||
return [
|
||||
'accounts' => [
|
||||
'class' => AccountFixture::class,
|
||||
'dataFile' => '@tests/codeception/common/fixtures/data/accounts.php',
|
||||
],
|
||||
'accounts' => AccountFixture::class,
|
||||
];
|
||||
}
|
||||
|
||||
@ -84,7 +65,7 @@ class RegistrationFormTest extends DbTestCase {
|
||||
$account = $model->signup();
|
||||
|
||||
$this->expectSuccessRegistration($account);
|
||||
expect('lang is set', $account->lang)->equals('ru');
|
||||
$this->assertEquals('ru', $account->lang, 'lang is set');
|
||||
}
|
||||
|
||||
public function testSignupWithDefaultLanguage() {
|
||||
@ -99,32 +80,32 @@ class RegistrationFormTest extends DbTestCase {
|
||||
$account = $model->signup();
|
||||
|
||||
$this->expectSuccessRegistration($account);
|
||||
expect('lang is set', $account->lang)->equals('en');
|
||||
$this->assertEquals('en', $account->lang, 'lang is set');
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Account|null $account
|
||||
*/
|
||||
private function expectSuccessRegistration($account) {
|
||||
expect('user should be valid', $account)->isInstanceOf(Account::class);
|
||||
expect('password should be correct', $account->validatePassword('some_password'))->true();
|
||||
expect('uuid is set', $account->uuid)->notEmpty();
|
||||
expect('registration_ip is set', $account->registration_ip)->notNull();
|
||||
expect('actual rules version is set', $account->rules_agreement_version)->equals(LATEST_RULES_VERSION);
|
||||
expect('user model exists in database', Account::find()->andWhere([
|
||||
$this->assertInstanceOf(Account::class, $account, 'user should be valid');
|
||||
$this->assertTrue($account->validatePassword('some_password'), 'password should be correct');
|
||||
$this->assertNotEmpty($account->uuid, 'uuid is set');
|
||||
$this->assertNotNull($account->registration_ip, 'registration_ip is set');
|
||||
$this->assertEquals(LATEST_RULES_VERSION, $account->rules_agreement_version, 'actual rules version is set');
|
||||
$this->assertTrue(Account::find()->andWhere([
|
||||
'username' => 'some_username',
|
||||
'email' => 'some_email@example.com',
|
||||
])->exists())->true();
|
||||
expect('email activation code exists in database', EmailActivation::find()->andWhere([
|
||||
])->exists(), 'user model exists in database');
|
||||
$this->assertTrue(EmailActivation::find()->andWhere([
|
||||
'account_id' => $account->id,
|
||||
'type' => EmailActivation::TYPE_REGISTRATION_EMAIL_CONFIRMATION,
|
||||
])->exists())->true();
|
||||
expect('username history record exists in database', UsernameHistory::find()->andWhere([
|
||||
])->exists(), 'email activation code exists in database');
|
||||
$this->assertTrue(UsernameHistory::find()->andWhere([
|
||||
'username' => $account->username,
|
||||
'account_id' => $account->id,
|
||||
'applied_in' => $account->created_at,
|
||||
])->exists())->true();
|
||||
expect_file('message file exists', $this->getMessageFile())->exists();
|
||||
])->exists(), 'username history record exists in database');
|
||||
$this->tester->canSeeEmailIsSent(1);
|
||||
}
|
||||
|
||||
// TODO: там в самой форме есть метод sendMail(), который рано или поздно должен переехать. К нему нужны будут тоже тесты
|
||||
@ -144,11 +125,4 @@ class RegistrationFormTest extends DbTestCase {
|
||||
return $request;
|
||||
}
|
||||
|
||||
private function getMessageFile() {
|
||||
/** @var \yii\swiftmailer\Mailer $mailer */
|
||||
$mailer = Yii::$app->mailer;
|
||||
|
||||
return Yii::getAlias($mailer->fileTransportPath) . '/testing_message.eml';
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -1,50 +1,30 @@
|
||||
<?php
|
||||
namespace tests\codeception\api\models\authentication;
|
||||
|
||||
use api\components\ReCaptcha\Validator;
|
||||
use api\components\ReCaptcha\Validator as ReCaptchaValidator;
|
||||
use api\models\authentication\RepeatAccountActivationForm;
|
||||
use Codeception\Specify;
|
||||
use common\models\EmailActivation;
|
||||
use tests\codeception\api\unit\DbTestCase;
|
||||
use tests\codeception\api\unit\TestCase;
|
||||
use tests\codeception\common\fixtures\AccountFixture;
|
||||
use tests\codeception\common\fixtures\EmailActivationFixture;
|
||||
use Yii;
|
||||
|
||||
/**
|
||||
* @property array $accounts
|
||||
* @property array $activations
|
||||
*/
|
||||
class RepeatAccountActivationFormTest extends DbTestCase {
|
||||
class RepeatAccountActivationFormTest extends TestCase {
|
||||
use Specify;
|
||||
|
||||
public function setUp() {
|
||||
parent::setUp();
|
||||
/** @var \yii\swiftmailer\Mailer $mailer */
|
||||
$mailer = Yii::$app->mailer;
|
||||
$mailer->fileTransportCallback = function () {
|
||||
return 'testing_message.eml';
|
||||
};
|
||||
Yii::$container->set(Validator::class, new class extends Validator {
|
||||
Yii::$container->set(ReCaptchaValidator::class, new class extends ReCaptchaValidator {
|
||||
public function validateValue($value) {
|
||||
return null;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
protected function tearDown() {
|
||||
if (file_exists($this->getMessageFile())) {
|
||||
unlink($this->getMessageFile());
|
||||
}
|
||||
|
||||
parent::tearDown();
|
||||
}
|
||||
|
||||
public function fixtures() {
|
||||
public function _fixtures() {
|
||||
return [
|
||||
'accounts' => [
|
||||
'class' => AccountFixture::class,
|
||||
'dataFile' => '@tests/codeception/common/fixtures/data/accounts.php',
|
||||
],
|
||||
'accounts' => AccountFixture::class,
|
||||
'activations' => EmailActivationFixture::class,
|
||||
];
|
||||
}
|
||||
@ -57,13 +37,15 @@ class RepeatAccountActivationFormTest extends DbTestCase {
|
||||
});
|
||||
|
||||
$this->specify('error.account_already_activated if passed valid email, but account already activated', function() {
|
||||
$model = new RepeatAccountActivationForm(['email' => $this->accounts['admin']['email']]);
|
||||
$fixture = $this->tester->grabFixture('accounts', 'admin');
|
||||
$model = new RepeatAccountActivationForm(['email' => $fixture['email']]);
|
||||
$model->validateEmailForAccount('email');
|
||||
expect($model->getErrors('email'))->equals(['error.account_already_activated']);
|
||||
});
|
||||
|
||||
$this->specify('no errors if passed valid email for not activated account', function() {
|
||||
$model = new RepeatAccountActivationForm(['email' => $this->accounts['not-activated-account']['email']]);
|
||||
$fixture = $this->tester->grabFixture('accounts', 'not-activated-account');
|
||||
$model = new RepeatAccountActivationForm(['email' => $fixture['email']]);
|
||||
$model->validateEmailForAccount('email');
|
||||
expect($model->getErrors('email'))->isEmpty();
|
||||
});
|
||||
@ -71,17 +53,15 @@ class RepeatAccountActivationFormTest extends DbTestCase {
|
||||
|
||||
public function testValidateExistsActivation() {
|
||||
$this->specify('error.recently_sent_message if passed email has recently sent message', function() {
|
||||
$model = $this->createModel([
|
||||
'emailKey' => $this->activations['freshRegistrationConfirmation']['key'],
|
||||
]);
|
||||
$fixture = $this->tester->grabFixture('activations', 'freshRegistrationConfirmation');
|
||||
$model = $this->createModel(['emailKey' => $fixture['key']]);
|
||||
$model->validateExistsActivation('email');
|
||||
expect($model->getErrors('email'))->equals(['error.recently_sent_message']);
|
||||
});
|
||||
|
||||
$this->specify('no errors if passed email has expired activation message', function() {
|
||||
$model = $this->createModel([
|
||||
'emailKey' => $this->activations['oldRegistrationConfirmation']['key'],
|
||||
]);
|
||||
$fixture = $this->tester->grabFixture('activations', 'oldRegistrationConfirmation');
|
||||
$model = $this->createModel(['emailKey' => $fixture['key']]);
|
||||
$model->validateExistsActivation('email');
|
||||
expect($model->getErrors('email'))->isEmpty();
|
||||
});
|
||||
@ -91,25 +71,18 @@ class RepeatAccountActivationFormTest extends DbTestCase {
|
||||
$this->specify('no magic if we don\'t pass validation', function() {
|
||||
$model = new RepeatAccountActivationForm();
|
||||
expect($model->sendRepeatMessage())->false();
|
||||
expect_file($this->getMessageFile())->notExists();
|
||||
$this->tester->cantSeeEmailIsSent();
|
||||
});
|
||||
|
||||
$this->specify('successfully send new message if previous message has expired', function() {
|
||||
$email = $this->accounts['not-activated-account-with-expired-message']['email'];
|
||||
$email = $this->tester->grabFixture('accounts', 'not-activated-account-with-expired-message')['email'];
|
||||
$model = new RepeatAccountActivationForm(['email' => $email]);
|
||||
expect($model->sendRepeatMessage())->true();
|
||||
expect($model->getActivation())->notNull();
|
||||
expect_file($this->getMessageFile())->exists();
|
||||
$this->tester->canSeeEmailIsSent(1);
|
||||
});
|
||||
}
|
||||
|
||||
private function getMessageFile() {
|
||||
/** @var \yii\swiftmailer\Mailer $mailer */
|
||||
$mailer = Yii::$app->mailer;
|
||||
|
||||
return Yii::getAlias($mailer->fileTransportPath) . '/testing_message.eml';
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array $params
|
||||
* @return RepeatAccountActivationForm
|
||||
|
@ -2,19 +2,14 @@
|
||||
namespace tests\codeception\api\models\base;
|
||||
|
||||
use api\models\base\ApiForm;
|
||||
use Codeception\Specify;
|
||||
use tests\codeception\api\unit\TestCase;
|
||||
|
||||
class ApiFormTest extends TestCase {
|
||||
|
||||
use Specify;
|
||||
|
||||
public function testLoad() {
|
||||
$model = new DummyApiForm();
|
||||
$this->specify('model should load data without ModelName array scope', function () use ($model) {
|
||||
expect('model successful load data without prefix', $model->load(['field' => 'test-data']))->true();
|
||||
expect('field is set as passed data', $model->field)->equals('test-data');
|
||||
});
|
||||
$this->assertTrue($model->load(['field' => 'test-data']), 'model successful load data without prefix');
|
||||
$this->assertEquals('test-data', $model->field, 'field is set as passed data');
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -4,34 +4,26 @@ namespace tests\codeception\api\models\base;
|
||||
use api\models\base\KeyConfirmationForm;
|
||||
use Codeception\Specify;
|
||||
use common\models\EmailActivation;
|
||||
use tests\codeception\api\unit\DbTestCase;
|
||||
use tests\codeception\api\unit\TestCase;
|
||||
use tests\codeception\common\fixtures\EmailActivationFixture;
|
||||
use Yii;
|
||||
|
||||
/**
|
||||
* @property EmailActivationFixture $emailActivations
|
||||
*/
|
||||
class KeyConfirmationFormTest extends DbTestCase {
|
||||
class KeyConfirmationFormTest extends TestCase {
|
||||
use Specify;
|
||||
|
||||
public function fixtures() {
|
||||
public function _fixtures() {
|
||||
return [
|
||||
'emailActivations' => EmailActivationFixture::class,
|
||||
];
|
||||
}
|
||||
|
||||
public function testGetActivationCodeModel() {
|
||||
$this->specify('should return model, based on passed key', function() {
|
||||
$model = new KeyConfirmationForm();
|
||||
$model->key = array_values($this->emailActivations->data)[0]['key'];
|
||||
expect($model->getActivationCodeModel())->isInstanceOf(EmailActivation::class);
|
||||
});
|
||||
$model = new KeyConfirmationForm();
|
||||
$model->key = $this->tester->grabFixture('emailActivations', 'freshRegistrationConfirmation')['key'];
|
||||
$this->assertInstanceOf(EmailActivation::class, $model->getActivationCodeModel());
|
||||
|
||||
$this->specify('should return null, if passed key is invalid', function() {
|
||||
$model = new KeyConfirmationForm();
|
||||
$model->key = 'this-is-invalid-key';
|
||||
expect($model->getActivationCodeModel())->null();
|
||||
});
|
||||
$model = new KeyConfirmationForm();
|
||||
$model->key = 'this-is-invalid-key';
|
||||
$this->assertNull($model->getActivationCodeModel());
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -2,32 +2,25 @@
|
||||
namespace codeception\api\unit\models\profile;
|
||||
|
||||
use api\models\profile\AcceptRulesForm;
|
||||
use Codeception\Specify;
|
||||
use common\models\Account;
|
||||
use tests\codeception\api\unit\DbTestCase;
|
||||
use tests\codeception\api\unit\TestCase;
|
||||
use tests\codeception\common\fixtures\AccountFixture;
|
||||
use const common\LATEST_RULES_VERSION;
|
||||
|
||||
/**
|
||||
* @property AccountFixture $accounts
|
||||
*/
|
||||
class AcceptRulesFormTest extends DbTestCase {
|
||||
use Specify;
|
||||
class AcceptRulesFormTest extends TestCase {
|
||||
|
||||
public function fixtures() {
|
||||
public function _fixtures() {
|
||||
return [
|
||||
'accounts' => AccountFixture::class,
|
||||
];
|
||||
}
|
||||
|
||||
public function testApplyLanguage() {
|
||||
$this->specify('rules version bumped to latest', function() {
|
||||
/** @var Account $account */
|
||||
$account = Account::findOne($this->accounts['account-with-old-rules-version']);
|
||||
$model = new AcceptRulesForm($account);
|
||||
expect($model->agreeWithLatestRules())->true();
|
||||
expect($account->rules_agreement_version)->equals(LATEST_RULES_VERSION);
|
||||
});
|
||||
public function testAgreeWithLatestRules() {
|
||||
/** @var Account $account */
|
||||
$account = Account::findOne($this->tester->grabFixture('accounts', 'account-with-old-rules-version'));
|
||||
$model = new AcceptRulesForm($account);
|
||||
$this->assertTrue($model->agreeWithLatestRules());
|
||||
$this->assertEquals(LATEST_RULES_VERSION, $account->rules_agreement_version);
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -2,46 +2,36 @@
|
||||
namespace codeception\api\unit\models\profile\ChangeEmail;
|
||||
|
||||
use api\models\profile\ChangeEmail\ConfirmNewEmailForm;
|
||||
use Codeception\Specify;
|
||||
use common\models\Account;
|
||||
use common\models\EmailActivation;
|
||||
use tests\codeception\api\unit\DbTestCase;
|
||||
use tests\codeception\api\unit\TestCase;
|
||||
use tests\codeception\common\fixtures\AccountFixture;
|
||||
use tests\codeception\common\fixtures\EmailActivationFixture;
|
||||
use Yii;
|
||||
|
||||
/**
|
||||
* @property AccountFixture $accounts
|
||||
* @property EmailActivationFixture $emailActivations
|
||||
*/
|
||||
class ConfirmNewEmailFormTest extends DbTestCase {
|
||||
use Specify;
|
||||
class ConfirmNewEmailFormTest extends TestCase {
|
||||
|
||||
public function fixtures() {
|
||||
public function _fixtures() {
|
||||
return [
|
||||
'accounts' => [
|
||||
'class' => AccountFixture::class,
|
||||
'dataFile' => '@tests/codeception/common/fixtures/data/accounts.php',
|
||||
],
|
||||
'accounts' => AccountFixture::class,
|
||||
'emailActivations' => EmailActivationFixture::class,
|
||||
];
|
||||
}
|
||||
|
||||
public function testChangeEmail() {
|
||||
$this->specify('successfully change account email', function() {
|
||||
/** @var Account $account */
|
||||
$account = Account::findOne($this->accounts['account-with-change-email-finish-state']['id']);
|
||||
$model = new ConfirmNewEmailForm($account, [
|
||||
'key' => $this->emailActivations['newEmailConfirmation']['key'],
|
||||
]);
|
||||
expect($model->changeEmail())->true();
|
||||
expect(EmailActivation::findOne([
|
||||
'account_id' => $account->id,
|
||||
'type' => EmailActivation::TYPE_NEW_EMAIL_CONFIRMATION,
|
||||
]))->null();
|
||||
$data = unserialize($this->emailActivations['newEmailConfirmation']['_data']);
|
||||
expect($account->email)->equals($data['newEmail']);
|
||||
});
|
||||
$accountId = $this->tester->grabFixture('accounts', 'account-with-change-email-finish-state')['id'];
|
||||
/** @var Account $account */
|
||||
$account = Account::findOne($accountId);
|
||||
$newEmailConfirmationFixture = $this->tester->grabFixture('emailActivations', 'newEmailConfirmation');
|
||||
$model = new ConfirmNewEmailForm($account, [
|
||||
'key' => $newEmailConfirmationFixture['key'],
|
||||
]);
|
||||
$this->assertTrue($model->changeEmail());
|
||||
$this->assertNull(EmailActivation::findOne([
|
||||
'account_id' => $account->id,
|
||||
'type' => EmailActivation::TYPE_NEW_EMAIL_CONFIRMATION,
|
||||
]));
|
||||
$data = unserialize($newEmailConfirmationFixture['_data']);
|
||||
$this->assertEquals($data['newEmail'], $account->email);
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -2,82 +2,44 @@
|
||||
namespace codeception\api\unit\models\profile\ChangeEmail;
|
||||
|
||||
use api\models\profile\ChangeEmail\InitStateForm;
|
||||
use Codeception\Specify;
|
||||
use common\models\Account;
|
||||
use common\models\confirmations\CurrentEmailConfirmation;
|
||||
use common\models\EmailActivation;
|
||||
use tests\codeception\api\unit\DbTestCase;
|
||||
use tests\codeception\api\unit\TestCase;
|
||||
use tests\codeception\common\fixtures\AccountFixture;
|
||||
use tests\codeception\common\fixtures\EmailActivationFixture;
|
||||
use Yii;
|
||||
|
||||
/**
|
||||
* @property AccountFixture $accounts
|
||||
* @property EmailActivationFixture $emailActivations
|
||||
*/
|
||||
class InitStateFormTest extends DbTestCase {
|
||||
use Specify;
|
||||
class InitStateFormTest extends TestCase {
|
||||
|
||||
public function setUp() {
|
||||
parent::setUp();
|
||||
/** @var \yii\swiftmailer\Mailer $mailer */
|
||||
$mailer = Yii::$app->mailer;
|
||||
$mailer->fileTransportCallback = function () {
|
||||
return 'testing_message.eml';
|
||||
};
|
||||
}
|
||||
|
||||
protected function tearDown() {
|
||||
if (file_exists($this->getMessageFile())) {
|
||||
unlink($this->getMessageFile());
|
||||
}
|
||||
|
||||
parent::tearDown();
|
||||
}
|
||||
|
||||
public function fixtures() {
|
||||
public function _fixtures() {
|
||||
return [
|
||||
'accounts' => [
|
||||
'class' => AccountFixture::class,
|
||||
'dataFile' => '@tests/codeception/common/fixtures/data/accounts.php',
|
||||
],
|
||||
'accounts' => AccountFixture::class,
|
||||
'emailActivations' => EmailActivationFixture::class,
|
||||
];
|
||||
}
|
||||
|
||||
public function testCreateCode() {
|
||||
$this->specify('create valid code and store it to database', function() {
|
||||
/** @var Account $account */
|
||||
$account = Account::findOne($this->accounts['admin']['id']);
|
||||
$model = new InitStateForm($account);
|
||||
$activationModel = $model->createCode();
|
||||
expect($activationModel)->isInstanceOf(CurrentEmailConfirmation::class);
|
||||
expect($activationModel->account_id)->equals($account->id);
|
||||
expect(EmailActivation::findOne($activationModel->key))->notNull();
|
||||
});
|
||||
/** @var Account $account */
|
||||
$account = $this->tester->grabFixture('accounts', 'admin');
|
||||
$model = new InitStateForm($account);
|
||||
$activationModel = $model->createCode();
|
||||
$this->assertInstanceOf(CurrentEmailConfirmation::class, $activationModel);
|
||||
$this->assertEquals($account->id, $activationModel->account_id);
|
||||
$this->assertNotNull(EmailActivation::findOne($activationModel->key));
|
||||
}
|
||||
|
||||
public function testSendCurrentEmailConfirmation() {
|
||||
$this->specify('send email', function() {
|
||||
/** @var Account $account */
|
||||
$account = Account::findOne($this->accounts['admin']['id']);
|
||||
$model = new InitStateForm($account, [
|
||||
'password' => 'password_0',
|
||||
]);
|
||||
expect($model->sendCurrentEmailConfirmation())->true();
|
||||
expect(EmailActivation::find()->andWhere([
|
||||
'account_id' => $account->id,
|
||||
'type' => EmailActivation::TYPE_CURRENT_EMAIL_CONFIRMATION,
|
||||
])->exists())->true();
|
||||
expect_file($this->getMessageFile())->exists();
|
||||
});
|
||||
}
|
||||
|
||||
private function getMessageFile() {
|
||||
/** @var \yii\swiftmailer\Mailer $mailer */
|
||||
$mailer = Yii::$app->mailer;
|
||||
|
||||
return Yii::getAlias($mailer->fileTransportPath) . '/testing_message.eml';
|
||||
/** @var Account $account */
|
||||
$account = $this->tester->grabFixture('accounts', 'admin');
|
||||
$model = new InitStateForm($account, [
|
||||
'password' => 'password_0',
|
||||
]);
|
||||
$this->assertTrue($model->sendCurrentEmailConfirmation());
|
||||
$this->assertTrue(EmailActivation::find()->andWhere([
|
||||
'account_id' => $account->id,
|
||||
'type' => EmailActivation::TYPE_CURRENT_EMAIL_CONFIRMATION,
|
||||
])->exists());
|
||||
$this->tester->canSeeEmailIsSent();
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -2,87 +2,50 @@
|
||||
namespace codeception\api\unit\models\profile\ChangeEmail;
|
||||
|
||||
use api\models\profile\ChangeEmail\NewEmailForm;
|
||||
use Codeception\Specify;
|
||||
use common\models\Account;
|
||||
use common\models\confirmations\NewEmailConfirmation;
|
||||
use common\models\EmailActivation;
|
||||
use tests\codeception\api\unit\DbTestCase;
|
||||
use tests\codeception\api\unit\TestCase;
|
||||
use tests\codeception\common\fixtures\AccountFixture;
|
||||
use tests\codeception\common\fixtures\EmailActivationFixture;
|
||||
use Yii;
|
||||
|
||||
/**
|
||||
* @property AccountFixture $accounts
|
||||
* @property EmailActivationFixture $emailActivations
|
||||
*/
|
||||
class NewEmailFormTest extends DbTestCase {
|
||||
use Specify;
|
||||
class NewEmailFormTest extends TestCase {
|
||||
|
||||
public function setUp() {
|
||||
parent::setUp();
|
||||
/** @var \yii\swiftmailer\Mailer $mailer */
|
||||
$mailer = Yii::$app->mailer;
|
||||
$mailer->fileTransportCallback = function () {
|
||||
return 'testing_message.eml';
|
||||
};
|
||||
}
|
||||
|
||||
protected function tearDown() {
|
||||
if (file_exists($this->getMessageFile())) {
|
||||
unlink($this->getMessageFile());
|
||||
}
|
||||
|
||||
parent::tearDown();
|
||||
}
|
||||
|
||||
public function fixtures() {
|
||||
public function _fixtures() {
|
||||
return [
|
||||
'accounts' => [
|
||||
'class' => AccountFixture::class,
|
||||
'dataFile' => '@tests/codeception/common/fixtures/data/accounts.php',
|
||||
],
|
||||
'accounts' => AccountFixture::class,
|
||||
'emailActivations' => EmailActivationFixture::class,
|
||||
];
|
||||
}
|
||||
|
||||
public function testCreateCode() {
|
||||
$this->specify('create valid code and store it to database', function() {
|
||||
/** @var Account $account */
|
||||
$account = Account::findOne($this->accounts['admin']['id']);
|
||||
$model = new NewEmailForm($account);
|
||||
$model->email = 'my-new-email@ely.by';
|
||||
$activationModel = $model->createCode();
|
||||
expect($activationModel)->isInstanceOf(NewEmailConfirmation::class);
|
||||
expect($activationModel->account_id)->equals($account->id);
|
||||
expect($activationModel->newEmail)->equals($model->email);
|
||||
expect(EmailActivation::findOne($activationModel->key))->notNull();
|
||||
});
|
||||
/** @var Account $account */
|
||||
$account = $this->tester->grabFixture('accounts', 'admin');
|
||||
$model = new NewEmailForm($account);
|
||||
$model->email = 'my-new-email@ely.by';
|
||||
$activationModel = $model->createCode();
|
||||
$this->assertInstanceOf(NewEmailConfirmation::class, $activationModel);
|
||||
$this->assertEquals($account->id, $activationModel->account_id);
|
||||
$this->assertEquals($model->email, $activationModel->newEmail);
|
||||
$this->assertNotNull(EmailActivation::findOne($activationModel->key));
|
||||
}
|
||||
|
||||
public function testSendNewEmailConfirmation() {
|
||||
$this->specify('send email', function() {
|
||||
/** @var Account $account */
|
||||
$account = Account::findOne($this->accounts['account-with-change-email-init-state']['id']);
|
||||
/** @var NewEmailForm $model */
|
||||
$key = $this->emailActivations['currentChangeEmailConfirmation']['key'];
|
||||
$model = new NewEmailForm($account, [
|
||||
'key' => $key,
|
||||
'email' => 'my-new-email@ely.by',
|
||||
]);
|
||||
expect($model->sendNewEmailConfirmation())->true();
|
||||
expect(EmailActivation::findOne($key))->null();
|
||||
expect(EmailActivation::findOne([
|
||||
'account_id' => $account->id,
|
||||
'type' => EmailActivation::TYPE_NEW_EMAIL_CONFIRMATION,
|
||||
]))->notNull();
|
||||
expect_file($this->getMessageFile())->exists();
|
||||
});
|
||||
}
|
||||
|
||||
private function getMessageFile() {
|
||||
/** @var \yii\swiftmailer\Mailer $mailer */
|
||||
$mailer = Yii::$app->mailer;
|
||||
return Yii::getAlias($mailer->fileTransportPath) . '/testing_message.eml';
|
||||
/** @var Account $account */
|
||||
$account = $this->tester->grabFixture('accounts', 'account-with-change-email-init-state');
|
||||
/** @var NewEmailForm $model */
|
||||
$key = $this->tester->grabFixture('emailActivations', 'currentChangeEmailConfirmation')['key'];
|
||||
$model = new NewEmailForm($account, [
|
||||
'key' => $key,
|
||||
'email' => 'my-new-email@ely.by',
|
||||
]);
|
||||
$this->assertTrue($model->sendNewEmailConfirmation());
|
||||
$this->assertNull(EmailActivation::findOne($key));
|
||||
$this->assertNotNull(EmailActivation::findOne([
|
||||
'account_id' => $account->id,
|
||||
'type' => EmailActivation::TYPE_NEW_EMAIL_CONFIRMATION,
|
||||
]));
|
||||
$this->tester->canSeeEmailIsSent();
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -2,35 +2,25 @@
|
||||
namespace codeception\api\unit\models\profile;
|
||||
|
||||
use api\models\profile\ChangeLanguageForm;
|
||||
use Codeception\Specify;
|
||||
use common\models\Account;
|
||||
use tests\codeception\api\unit\DbTestCase;
|
||||
use tests\codeception\api\unit\TestCase;
|
||||
use tests\codeception\common\fixtures\AccountFixture;
|
||||
|
||||
/**
|
||||
* @property AccountFixture $accounts
|
||||
*/
|
||||
class ChangeLanguageFormTest extends DbTestCase {
|
||||
use Specify;
|
||||
class ChangeLanguageFormTest extends TestCase {
|
||||
|
||||
public function fixtures() {
|
||||
public function _fixtures() {
|
||||
return [
|
||||
'accounts' => [
|
||||
'class' => AccountFixture::class,
|
||||
'dataFile' => '@tests/codeception/common/fixtures/data/accounts.php',
|
||||
],
|
||||
'accounts' => AccountFixture::class
|
||||
];
|
||||
}
|
||||
|
||||
public function testApplyLanguage() {
|
||||
$this->specify('language changed', function() {
|
||||
/** @var Account $account */
|
||||
$account = Account::findOne($this->accounts['admin']);
|
||||
$model = new ChangeLanguageForm($account);
|
||||
$model->lang = 'ru';
|
||||
expect($model->applyLanguage())->true();
|
||||
expect($account->lang)->equals('ru');
|
||||
});
|
||||
/** @var Account $account */
|
||||
$account = $this->tester->grabFixture('accounts', 'admin');
|
||||
$model = new ChangeLanguageForm($account);
|
||||
$model->lang = 'ru';
|
||||
$this->assertTrue($model->applyLanguage());
|
||||
$this->assertEquals('ru', $account->lang);
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -7,19 +7,15 @@ use api\models\profile\ChangePasswordForm;
|
||||
use Codeception\Specify;
|
||||
use common\models\Account;
|
||||
use common\models\AccountSession;
|
||||
use tests\codeception\api\unit\DbTestCase;
|
||||
use tests\codeception\api\unit\TestCase;
|
||||
use tests\codeception\common\fixtures\AccountFixture;
|
||||
use tests\codeception\common\fixtures\AccountSessionFixture;
|
||||
use Yii;
|
||||
|
||||
/**
|
||||
* @property AccountFixture $accounts
|
||||
* @property AccountSessionFixture $accountSessions
|
||||
*/
|
||||
class ChangePasswordFormTest extends DbTestCase {
|
||||
class ChangePasswordFormTest extends TestCase {
|
||||
use Specify;
|
||||
|
||||
public function fixtures() {
|
||||
public function _fixtures() {
|
||||
return [
|
||||
'accounts' => AccountFixture::class,
|
||||
'accountSessions' => AccountSessionFixture::class,
|
||||
@ -68,7 +64,7 @@ class ChangePasswordFormTest extends DbTestCase {
|
||||
public function testChangePassword() {
|
||||
$this->specify('successfully change password with modern hash strategy', function() {
|
||||
/** @var Account $account */
|
||||
$account = Account::findOne($this->accounts['admin']['id']);
|
||||
$account = Account::findOne($this->tester->grabFixture('accounts', 'admin')['id']);
|
||||
$model = new ChangePasswordForm($account, [
|
||||
'password' => 'password_0',
|
||||
'newPassword' => 'my-new-password',
|
||||
@ -83,7 +79,7 @@ class ChangePasswordFormTest extends DbTestCase {
|
||||
|
||||
$this->specify('successfully change password with legacy hash strategy', function() {
|
||||
/** @var Account $account */
|
||||
$account = Account::findOne($this->accounts['user-with-old-password-type']['id']);
|
||||
$account = Account::findOne($this->tester->grabFixture('accounts', 'user-with-old-password-type')['id']);
|
||||
$model = new ChangePasswordForm($account, [
|
||||
'password' => '12345678',
|
||||
'newPassword' => 'my-new-password',
|
||||
@ -111,7 +107,7 @@ class ChangePasswordFormTest extends DbTestCase {
|
||||
->getMock();
|
||||
|
||||
/** @var AccountSession $session */
|
||||
$session = AccountSession::findOne($this->accountSessions['admin2']['id']);
|
||||
$session = AccountSession::findOne($this->tester->grabFixture('accountSessions', 'admin2')['id']);
|
||||
|
||||
$component
|
||||
->expects($this->any())
|
||||
@ -122,7 +118,7 @@ class ChangePasswordFormTest extends DbTestCase {
|
||||
|
||||
$this->specify('change password with removing all session, except current', function() use ($session) {
|
||||
/** @var Account $account */
|
||||
$account = Account::findOne($this->accounts['admin']['id']);
|
||||
$account = Account::findOne($this->tester->grabFixture('accounts', 'admin')['id']);
|
||||
|
||||
$model = new ChangePasswordForm($account, [
|
||||
'password' => 'password_0',
|
||||
|
@ -6,18 +6,15 @@ use api\models\profile\ChangeUsernameForm;
|
||||
use Codeception\Specify;
|
||||
use common\models\Account;
|
||||
use common\models\UsernameHistory;
|
||||
use tests\codeception\api\unit\DbTestCase;
|
||||
use tests\codeception\api\unit\TestCase;
|
||||
use tests\codeception\common\fixtures\AccountFixture;
|
||||
use tests\codeception\common\fixtures\UsernameHistoryFixture;
|
||||
use Yii;
|
||||
|
||||
/**
|
||||
* @property AccountFixture $accounts
|
||||
*/
|
||||
class ChangeUsernameFormTest extends DbTestCase {
|
||||
class ChangeUsernameFormTest extends TestCase {
|
||||
use Specify;
|
||||
|
||||
public function fixtures() {
|
||||
public function _fixtures() {
|
||||
return [
|
||||
'accounts' => AccountFixture::class,
|
||||
'history' => UsernameHistoryFixture::class,
|
||||
@ -31,64 +28,43 @@ class ChangeUsernameFormTest extends DbTestCase {
|
||||
}
|
||||
|
||||
public function testChange() {
|
||||
$this->specify('successfully change username to new one', function() {
|
||||
$model = new ChangeUsernameForm([
|
||||
'password' => 'password_0',
|
||||
'username' => 'my_new_nickname',
|
||||
]);
|
||||
expect($model->change())->true();
|
||||
expect(Account::findOne($this->getAccountId())->username)->equals('my_new_nickname');
|
||||
expect(UsernameHistory::findOne(['username' => 'my_new_nickname']))->isInstanceOf(UsernameHistory::class);
|
||||
});
|
||||
$model = new ChangeUsernameForm([
|
||||
'password' => 'password_0',
|
||||
'username' => 'my_new_nickname',
|
||||
]);
|
||||
$this->assertTrue($model->change());
|
||||
$this->assertEquals('my_new_nickname', Account::findOne($this->getAccountId())->username);
|
||||
$this->assertInstanceOf(UsernameHistory::class, UsernameHistory::findOne(['username' => 'my_new_nickname']));
|
||||
}
|
||||
|
||||
public function testChangeWithoutChange() {
|
||||
$this->specify('no new UsernameHistory record, if we don\'t change nickname', function() {
|
||||
$model = new ChangeUsernameForm([
|
||||
'password' => 'password_0',
|
||||
'username' => $this->accounts['admin']['username'],
|
||||
]);
|
||||
$callTime = time();
|
||||
expect($model->change())->true();
|
||||
expect(UsernameHistory::findOne([
|
||||
'AND',
|
||||
'username' => $this->accounts['admin']['username'],
|
||||
['>=', 'applied_in', $callTime],
|
||||
]))->null();
|
||||
});
|
||||
$username = $this->tester->grabFixture('accounts', 'admin')['username'];
|
||||
$model = new ChangeUsernameForm([
|
||||
'password' => 'password_0',
|
||||
'username' => $username,
|
||||
]);
|
||||
$callTime = time();
|
||||
$this->assertTrue($model->change());
|
||||
$this->assertNull(UsernameHistory::findOne([
|
||||
'AND',
|
||||
'username' => $username,
|
||||
['>=', 'applied_in', $callTime],
|
||||
]), 'no new UsernameHistory record, if we don\'t change nickname');
|
||||
}
|
||||
|
||||
public function testChangeCase() {
|
||||
$this->specify('username should change, if we change case of some letters', function() {
|
||||
$newUsername = mb_strtoupper($this->accounts['admin']['username']);
|
||||
$model = new ChangeUsernameForm([
|
||||
'password' => 'password_0',
|
||||
'username' => $newUsername,
|
||||
]);
|
||||
expect($model->change())->true();
|
||||
expect(Account::findOne($this->getAccountId())->username)->equals($newUsername);
|
||||
expect(UsernameHistory::findOne(['username' => $newUsername]))->isInstanceOf(UsernameHistory::class);
|
||||
});
|
||||
}
|
||||
|
||||
public function testValidateUsername() {
|
||||
$this->specify('error.username_not_available expected if username is already taken', function() {
|
||||
$model = new ChangeUsernameForm([
|
||||
'password' => 'password_0',
|
||||
'username' => 'Jon',
|
||||
]);
|
||||
$model->validateUsername('username');
|
||||
expect($model->getErrors('username'))->equals(['error.username_not_available']);
|
||||
});
|
||||
|
||||
$this->specify('error.username_not_available is NOT expected if username is already taken by CURRENT user', function() {
|
||||
$model = new ChangeUsernameForm([
|
||||
'password' => 'password_0',
|
||||
'username' => $this->accounts['admin']['username'],
|
||||
]);
|
||||
$model->validateUsername('username');
|
||||
expect($model->getErrors('username'))->isEmpty();
|
||||
});
|
||||
$newUsername = mb_strtoupper($this->tester->grabFixture('accounts', 'admin')['username']);
|
||||
$model = new ChangeUsernameForm([
|
||||
'password' => 'password_0',
|
||||
'username' => $newUsername,
|
||||
]);
|
||||
$this->assertTrue($model->change());
|
||||
$this->assertEquals($newUsername, Account::findOne($this->getAccountId())->username);
|
||||
$this->assertInstanceOf(
|
||||
UsernameHistory::class,
|
||||
UsernameHistory::findOne(['username' => $newUsername]),
|
||||
'username should change, if we change case of some letters'
|
||||
);
|
||||
}
|
||||
|
||||
public function testCreateTask() {
|
||||
@ -99,7 +75,7 @@ class ChangeUsernameFormTest extends DbTestCase {
|
||||
}
|
||||
|
||||
private function getAccountId() {
|
||||
return $this->accounts['admin']['id'];
|
||||
return $this->tester->grabFixture('accounts', 'admin')['id'];
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -8,19 +8,15 @@ use api\modules\authserver\models\AuthenticationForm;
|
||||
use common\models\Account;
|
||||
use common\models\MinecraftAccessKey;
|
||||
use Ramsey\Uuid\Uuid;
|
||||
use tests\codeception\api\unit\DbTestCase;
|
||||
use tests\codeception\api\unit\TestCase;
|
||||
use tests\codeception\common\_support\ProtectedCaller;
|
||||
use tests\codeception\common\fixtures\AccountFixture;
|
||||
use tests\codeception\common\fixtures\MinecraftAccessKeyFixture;
|
||||
|
||||
/**
|
||||
* @property AccountFixture $accounts
|
||||
* @property MinecraftAccessKeyFixture $minecraftAccessKeys
|
||||
*/
|
||||
class AuthenticationFormTest extends DbTestCase {
|
||||
class AuthenticationFormTest extends TestCase {
|
||||
use ProtectedCaller;
|
||||
|
||||
public function fixtures() {
|
||||
public function _fixtures() {
|
||||
return [
|
||||
'accounts' => AccountFixture::class,
|
||||
'minecraftAccessKeys' => MinecraftAccessKeyFixture::class,
|
||||
@ -91,7 +87,7 @@ class AuthenticationFormTest extends DbTestCase {
|
||||
$authForm = new AuthenticationForm();
|
||||
$authForm->clientToken = Uuid::uuid4();
|
||||
/** @var Account $account */
|
||||
$account = $this->accounts->getModel('admin');
|
||||
$account = $this->tester->grabFixture('accounts', 'admin');
|
||||
/** @var MinecraftAccessKey $result */
|
||||
$result = $this->callProtected($authForm, 'createMinecraftAccessToken', $account);
|
||||
$this->assertInstanceOf(MinecraftAccessKey::class, $result);
|
||||
@ -102,15 +98,16 @@ class AuthenticationFormTest extends DbTestCase {
|
||||
|
||||
public function testCreateMinecraftAccessTokenWithExistsClientId() {
|
||||
$authForm = new AuthenticationForm();
|
||||
$authForm->clientToken = $this->minecraftAccessKeys['admin-token']['client_token'];
|
||||
$minecraftFixture = $this->tester->grabFixture('minecraftAccessKeys', 'admin-token');
|
||||
$authForm->clientToken = $minecraftFixture['client_token'];
|
||||
/** @var Account $account */
|
||||
$account = $this->accounts->getModel('admin');
|
||||
$account = $this->tester->grabFixture('accounts', 'admin');
|
||||
/** @var MinecraftAccessKey $result */
|
||||
$result = $this->callProtected($authForm, 'createMinecraftAccessToken', $account);
|
||||
$this->assertInstanceOf(MinecraftAccessKey::class, $result);
|
||||
$this->assertEquals($account->id, $result->account_id);
|
||||
$this->assertEquals($authForm->clientToken, $result->client_token);
|
||||
$this->assertNull(MinecraftAccessKey::findOne($this->minecraftAccessKeys['admin-token']['access_token']));
|
||||
$this->assertNull(MinecraftAccessKey::findOne($minecraftFixture['access_token']));
|
||||
$this->assertInstanceOf(MinecraftAccessKey::class, MinecraftAccessKey::findOne($result->access_token));
|
||||
}
|
||||
|
||||
|
@ -5,32 +5,27 @@ use api\models\AccountIdentity;
|
||||
use api\traits\AccountFinder;
|
||||
use Codeception\Specify;
|
||||
use common\models\Account;
|
||||
use tests\codeception\api\unit\DbTestCase;
|
||||
use tests\codeception\api\unit\TestCase;
|
||||
use tests\codeception\common\fixtures\AccountFixture;
|
||||
|
||||
/**
|
||||
* @property \tests\codeception\api\UnitTester $actor
|
||||
* @property array $accounts
|
||||
*/
|
||||
class AccountFinderTest extends DbTestCase {
|
||||
class AccountFinderTest extends TestCase {
|
||||
use Specify;
|
||||
|
||||
public function fixtures() {
|
||||
public function _fixtures() {
|
||||
return [
|
||||
'accounts' => [
|
||||
'class' => AccountFixture::class,
|
||||
'dataFile' => '@tests/codeception/common/fixtures/data/accounts.php',
|
||||
],
|
||||
'accounts' => AccountFixture::class,
|
||||
];
|
||||
}
|
||||
|
||||
public function testGetAccount() {
|
||||
$this->specify('founded account for passed login data', function() {
|
||||
$model = new AccountFinderTestTestClass();
|
||||
$model->login = $this->accounts['admin']['email'];
|
||||
/** @var Account $account */
|
||||
$account = $this->tester->grabFixture('accounts', 'admin');
|
||||
$model->login = $account->email;
|
||||
$account = $model->getAccount();
|
||||
expect($account)->isInstanceOf(Account::class);
|
||||
expect($account->id)->equals($this->accounts['admin']['id']);
|
||||
expect($account->id)->equals($account->id);
|
||||
});
|
||||
|
||||
$this->specify('founded account for passed login data with changed account model class name', function() {
|
||||
@ -40,10 +35,12 @@ class AccountFinderTest extends DbTestCase {
|
||||
return AccountIdentity::class;
|
||||
}
|
||||
};
|
||||
$model->login = $this->accounts['admin']['email'];
|
||||
/** @var Account $account */
|
||||
$account = $this->tester->grabFixture('accounts', 'admin');
|
||||
$model->login = $account->email;
|
||||
$account = $model->getAccount();
|
||||
expect($account)->isInstanceOf(AccountIdentity::class);
|
||||
expect($account->id)->equals($this->accounts['admin']['id']);
|
||||
expect($account->id)->equals($account->id);
|
||||
});
|
||||
|
||||
$this->specify('null, if account not founded', function() {
|
||||
|
@ -2,41 +2,34 @@
|
||||
namespace tests\codeception\api\traits;
|
||||
|
||||
use api\traits\ApiNormalize;
|
||||
use Codeception\Specify;
|
||||
use Codeception\TestCase\Test;
|
||||
use tests\codeception\api\unit\TestCase;
|
||||
|
||||
class ApiNormalizeTestClass {
|
||||
use ApiNormalize;
|
||||
}
|
||||
|
||||
/**
|
||||
* @property \tests\codeception\api\UnitTester $actor
|
||||
*/
|
||||
class ApiNormalizerTest extends Test {
|
||||
use Specify;
|
||||
class ApiNormalizerTest extends TestCase {
|
||||
|
||||
public function testNormalizeModelErrors() {
|
||||
$object = new ApiNormalizeTestClass();
|
||||
$this->specify('', function() use ($object) {
|
||||
$normalized = $object->normalizeModelErrors([
|
||||
'rulesAgreement' => [
|
||||
'error.you_must_accept_rules',
|
||||
],
|
||||
'email' => [
|
||||
'error.email_required',
|
||||
],
|
||||
'username' => [
|
||||
'error.username_too_short',
|
||||
'error.username_not_unique',
|
||||
],
|
||||
]);
|
||||
$normalized = $object->normalizeModelErrors([
|
||||
'rulesAgreement' => [
|
||||
'error.you_must_accept_rules',
|
||||
],
|
||||
'email' => [
|
||||
'error.email_required',
|
||||
],
|
||||
'username' => [
|
||||
'error.username_too_short',
|
||||
'error.username_not_unique',
|
||||
],
|
||||
]);
|
||||
|
||||
expect($normalized)->equals([
|
||||
'rulesAgreement' => 'error.you_must_accept_rules',
|
||||
'email' => 'error.email_required',
|
||||
'username' => 'error.username_too_short',
|
||||
]);
|
||||
});
|
||||
$this->assertEquals([
|
||||
'rulesAgreement' => 'error.you_must_accept_rules',
|
||||
'email' => 'error.email_required',
|
||||
'username' => 'error.username_too_short',
|
||||
], $normalized);
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -5,18 +5,15 @@ use api\validators\EmailActivationKeyValidator;
|
||||
use Codeception\Specify;
|
||||
use common\models\confirmations\ForgotPassword;
|
||||
use common\models\EmailActivation;
|
||||
use tests\codeception\api\unit\DbTestCase;
|
||||
use tests\codeception\api\unit\TestCase;
|
||||
use tests\codeception\common\_support\ProtectedCaller;
|
||||
use tests\codeception\common\fixtures\EmailActivationFixture;
|
||||
|
||||
/**
|
||||
* @property EmailActivationFixture $emailActivations
|
||||
*/
|
||||
class EmailActivationKeyValidatorTest extends DbTestCase {
|
||||
class EmailActivationKeyValidatorTest extends TestCase {
|
||||
use Specify;
|
||||
use ProtectedCaller;
|
||||
|
||||
public function fixtures() {
|
||||
public function _fixtures() {
|
||||
return [
|
||||
'emailActivations' => EmailActivationFixture::class,
|
||||
];
|
||||
@ -24,7 +21,7 @@ class EmailActivationKeyValidatorTest extends DbTestCase {
|
||||
|
||||
public function testFindEmailActivationModel() {
|
||||
$this->specify('get EmailActivation model for exists key', function() {
|
||||
$key = array_values($this->emailActivations->data)[0]['key'];
|
||||
$key = $this->tester->grabFixture('emailActivations', 'freshRegistrationConfirmation')['key'];
|
||||
$model = new EmailActivationKeyValidator();
|
||||
/** @var EmailActivation $result */
|
||||
$result = $this->callProtected($model, 'findEmailActivationModel', $key);
|
||||
|
@ -4,11 +4,11 @@ namespace codeception\api\unit\validators;
|
||||
use api\validators\PasswordRequiredValidator;
|
||||
use Codeception\Specify;
|
||||
use common\models\Account;
|
||||
use tests\codeception\api\unit\DbTestCase;
|
||||
use tests\codeception\api\unit\TestCase;
|
||||
use tests\codeception\common\_support\ProtectedCaller;
|
||||
use common\helpers\Error as E;
|
||||
|
||||
class PasswordRequiredValidatorTest extends DbTestCase {
|
||||
class PasswordRequiredValidatorTest extends TestCase {
|
||||
use Specify;
|
||||
use ProtectedCaller;
|
||||
|
||||
|
@ -16,6 +16,8 @@ use yii\test\InitDbFixture;
|
||||
/**
|
||||
* This helper is used to populate the database with needed fixtures before any tests are run.
|
||||
* All fixtures will be loaded before the suite is started and unloaded after it completes.
|
||||
*
|
||||
* TODO: try to remove
|
||||
*/
|
||||
class FixtureHelper extends Module {
|
||||
|
||||
@ -52,14 +54,8 @@ class FixtureHelper extends Module {
|
||||
'accountSessions' => AccountSessionFixture::class,
|
||||
'emailActivations' => EmailActivationFixture::class,
|
||||
'usernamesHistory' => UsernameHistoryFixture::class,
|
||||
'oauthClients' => [
|
||||
'class' => OauthClientFixture::class,
|
||||
'dataFile' => '@tests/codeception/common/fixtures/data/oauth-clients.php',
|
||||
],
|
||||
'oauthSessions' => [
|
||||
'class' => OauthSessionFixture::class,
|
||||
'dataFile' => '@tests/codeception/common/fixtures/data/oauth-sessions.php',
|
||||
],
|
||||
'oauthClients' => OauthClientFixture::class,
|
||||
'oauthSessions' => OauthSessionFixture::class,
|
||||
'minecraftAccessKeys' => MinecraftAccessKeyFixture::class,
|
||||
];
|
||||
}
|
||||
|
@ -8,4 +8,6 @@ class MojangUsernameFixture extends ActiveFixture {
|
||||
|
||||
public $modelClass = MojangUsername::class;
|
||||
|
||||
public $dataFile = '@tests/codeception/common/fixtures/data/mojang-usernames.php';
|
||||
|
||||
}
|
||||
|
@ -8,6 +8,8 @@ class OauthClientFixture extends ActiveFixture {
|
||||
|
||||
public $modelClass = OauthClient::class;
|
||||
|
||||
public $dataFile = '@tests/codeception/common/fixtures/data/oauth-clients.php';
|
||||
|
||||
public $depends = [
|
||||
AccountFixture::class,
|
||||
];
|
||||
|
@ -9,6 +9,8 @@ class OauthSessionFixture extends ActiveFixture {
|
||||
|
||||
public $modelClass = OauthSession::class;
|
||||
|
||||
public $dataFile = '@tests/codeception/common/fixtures/data/oauth-sessions.php';
|
||||
|
||||
public $depends = [
|
||||
OauthClientFixture::class,
|
||||
AccountFixture::class,
|
||||
|
@ -1,6 +1,8 @@
|
||||
# Codeception Test Suite Configuration
|
||||
|
||||
# suite for unit (internal) tests.
|
||||
# RUN `build` COMMAND AFTER ADDING/REMOVING MODULES.
|
||||
|
||||
class_name: UnitTester
|
||||
modules:
|
||||
enabled:
|
||||
- Yii2:
|
||||
part: [orm, email, fixtures]
|
||||
config:
|
||||
Yii2:
|
||||
configFile: '../config/common/unit.php'
|
||||
|
@ -1,11 +0,0 @@
|
||||
<?php
|
||||
|
||||
namespace tests\codeception\common\unit;
|
||||
|
||||
/**
|
||||
* @inheritdoc
|
||||
*/
|
||||
class DbTestCase extends \yii\codeception\DbTestCase
|
||||
{
|
||||
public $appConfig = '@tests/codeception/config/common/unit.php';
|
||||
}
|
@ -1,8 +1,22 @@
|
||||
<?php
|
||||
namespace tests\codeception\common\unit;
|
||||
|
||||
class TestCase extends \yii\codeception\TestCase {
|
||||
class TestCase extends \Codeception\Test\Unit {
|
||||
|
||||
public $appConfig = '@tests/codeception/config/common/unit.php';
|
||||
/**
|
||||
* @var \tests\codeception\common\UnitTester
|
||||
*/
|
||||
protected $tester;
|
||||
|
||||
/**
|
||||
* Список фикстур, что будут загружены перед тестом, но после зачистки базы данных
|
||||
*
|
||||
* @url http://codeception.com/docs/modules/Yii2#fixtures
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function _fixtures() {
|
||||
return [];
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -13,23 +13,19 @@ class DataBehaviorTest extends TestCase {
|
||||
use ProtectedCaller;
|
||||
|
||||
public function testSetKey() {
|
||||
$this->specify('setting value should change model data field', function() {
|
||||
$model = $this->createModel();
|
||||
/** @var DataBehavior $behavior */
|
||||
$behavior = $model->behaviors['dataBehavior'];
|
||||
$this->callProtected($behavior, 'setKey', 'my-key', 'my-value');
|
||||
expect($model->_data)->equals(serialize(['my-key' => 'my-value']));
|
||||
});
|
||||
$model = $this->createModel();
|
||||
/** @var DataBehavior $behavior */
|
||||
$behavior = $model->behaviors['dataBehavior'];
|
||||
$this->callProtected($behavior, 'setKey', 'my-key', 'my-value');
|
||||
$this->assertEquals(serialize(['my-key' => 'my-value']), $model->_data);
|
||||
}
|
||||
|
||||
public function testGetKey() {
|
||||
$this->specify('getting value from exists data should work', function() {
|
||||
$model = $this->createModel();
|
||||
$model->_data = serialize(['some-key' => 'some-value']);
|
||||
/** @var DataBehavior $behavior */
|
||||
$behavior = $model->behaviors['dataBehavior'];
|
||||
expect($this->callProtected($behavior, 'getKey', 'some-key'))->equals('some-value');
|
||||
});
|
||||
$model = $this->createModel();
|
||||
$model->_data = serialize(['some-key' => 'some-value']);
|
||||
/** @var DataBehavior $behavior */
|
||||
$behavior = $model->behaviors['dataBehavior'];
|
||||
$this->assertEquals('some-value', $this->callProtected($behavior, 'getKey', 'some-key'));
|
||||
}
|
||||
|
||||
public function testGetData() {
|
||||
|
@ -12,12 +12,10 @@ class EmailActivationExpirationBehaviorTest extends TestCase {
|
||||
use ProtectedCaller;
|
||||
|
||||
public function testCalculateTime() {
|
||||
$this->specify('just use create_time and plus passed time', function() {
|
||||
$behavior = $this->createBehavior();
|
||||
$time = time();
|
||||
$behavior->owner->created_at = $time;
|
||||
expect($this->callProtected($behavior, 'calculateTime', 10))->equals($time + 10);
|
||||
});
|
||||
$behavior = $this->createBehavior();
|
||||
$time = time();
|
||||
$behavior->owner->created_at = $time;
|
||||
$this->assertEquals($time + 10, $this->callProtected($behavior, 'calculateTime', 10));
|
||||
}
|
||||
|
||||
public function testCompareTime() {
|
||||
|
54
tests/codeception/common/unit/components/Mojang/ApiTest.php
Normal file
54
tests/codeception/common/unit/components/Mojang/ApiTest.php
Normal file
@ -0,0 +1,54 @@
|
||||
<?php
|
||||
namespace codeception\common\unit\components\Mojang;
|
||||
|
||||
use common\components\Mojang\Api;
|
||||
use common\components\Mojang\response\UsernameToUUIDResponse;
|
||||
use GuzzleHttp\Client as GuzzleClient;
|
||||
use GuzzleHttp\Handler\MockHandler;
|
||||
use GuzzleHttp\HandlerStack;
|
||||
use GuzzleHttp\Psr7\Response;
|
||||
use tests\codeception\common\unit\TestCase;
|
||||
use Yii;
|
||||
|
||||
class ApiTest extends TestCase {
|
||||
|
||||
/**
|
||||
* @var MockHandler
|
||||
*/
|
||||
private $handler;
|
||||
|
||||
public function _before() {
|
||||
parent::_before();
|
||||
|
||||
$this->handler = new MockHandler();
|
||||
$handler = HandlerStack::create($this->handler);
|
||||
Yii::$app->set('guzzle', new GuzzleClient([
|
||||
'handler' => $handler,
|
||||
]));
|
||||
}
|
||||
|
||||
public function testUsernameToUUID() {
|
||||
$this->handler->append(new Response(200, [], '{"id": "7125ba8b1c864508b92bb5c042ccfe2b","name": "KrisJelbring"}'));
|
||||
$response = (new Api())->usernameToUUID('KrisJelbring');
|
||||
$this->assertInstanceOf(UsernameToUUIDResponse::class, $response);
|
||||
$this->assertEquals('7125ba8b1c864508b92bb5c042ccfe2b', $response->id);
|
||||
$this->assertEquals('KrisJelbring', $response->name);
|
||||
}
|
||||
|
||||
/**
|
||||
* @expectedException \common\components\Mojang\exceptions\NoContentException
|
||||
*/
|
||||
public function testUsernameToUUIDNoContent() {
|
||||
$this->handler->append(new Response(204));
|
||||
(new Api())->usernameToUUID('some-non-exists-user');
|
||||
}
|
||||
|
||||
/**
|
||||
* @expectedException \GuzzleHttp\Exception\RequestException
|
||||
*/
|
||||
public function testUsernameToUUID404() {
|
||||
$this->handler->append(new Response(404, [], '{"error":"Not Found","errorMessage":"The server has not found anything matching the request URI"}'));
|
||||
(new Api())->usernameToUUID('#hashedNickname');
|
||||
}
|
||||
|
||||
}
|
@ -1,35 +1,27 @@
|
||||
<?php
|
||||
namespace codeception\common\unit\models;
|
||||
|
||||
use Codeception\Specify;
|
||||
use common\models\AccountSession;
|
||||
use tests\codeception\common\unit\TestCase;
|
||||
|
||||
class AccountSessionTest extends TestCase {
|
||||
use Specify;
|
||||
|
||||
public function testGenerateRefreshToken() {
|
||||
$this->specify('method call will set refresh_token value', function() {
|
||||
$model = new AccountSession();
|
||||
$model->generateRefreshToken();
|
||||
expect($model->refresh_token)->notNull();
|
||||
});
|
||||
$model = new AccountSession();
|
||||
$model->generateRefreshToken();
|
||||
$this->assertNotNull($model->refresh_token, 'method call will set refresh_token value');
|
||||
}
|
||||
|
||||
public function testSetIp() {
|
||||
$this->specify('method should convert passed ip string to long', function() {
|
||||
$model = new AccountSession();
|
||||
$model->setIp('127.0.0.1');
|
||||
expect($model->last_used_ip)->equals(2130706433);
|
||||
});
|
||||
$model = new AccountSession();
|
||||
$model->setIp('127.0.0.1');
|
||||
$this->assertEquals(2130706433, $model->last_used_ip, 'method should convert passed ip string to long');
|
||||
}
|
||||
|
||||
public function testGetReadableIp() {
|
||||
$this->specify('method should convert stored ip long into readable ip string', function() {
|
||||
$model = new AccountSession();
|
||||
$model->last_used_ip = 2130706433;
|
||||
expect($model->getReadableIp())->equals('127.0.0.1');
|
||||
});
|
||||
$model = new AccountSession();
|
||||
$model->last_used_ip = 2130706433;
|
||||
$this->assertEquals('127.0.0.1', $model->getReadableIp(), 'method should convert stored long into readable ip');
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -4,127 +4,20 @@ namespace tests\codeception\common\unit\models;
|
||||
use Codeception\Specify;
|
||||
use common\components\UserPass;
|
||||
use common\models\Account;
|
||||
use tests\codeception\common\fixtures\AccountFixture;
|
||||
use tests\codeception\common\fixtures\MojangUsernameFixture;
|
||||
use tests\codeception\common\unit\DbTestCase;
|
||||
use tests\codeception\common\unit\TestCase;
|
||||
use Yii;
|
||||
use const common\LATEST_RULES_VERSION;
|
||||
|
||||
/**
|
||||
* @property array $accounts
|
||||
* @property array $mojangAccounts
|
||||
*/
|
||||
class AccountTest extends DbTestCase {
|
||||
class AccountTest extends TestCase {
|
||||
use Specify;
|
||||
|
||||
public function fixtures() {
|
||||
return [
|
||||
'accounts' => [
|
||||
'class' => AccountFixture::class,
|
||||
'dataFile' => '@tests/codeception/common/fixtures/data/accounts.php',
|
||||
],
|
||||
'mojangAccounts' => [
|
||||
'class' => MojangUsernameFixture::class,
|
||||
'dataFile' => '@tests/codeception/common/fixtures/data/mojang-usernames.php',
|
||||
],
|
||||
];
|
||||
}
|
||||
|
||||
public function testValidateUsername() {
|
||||
$this->specify('username required', function() {
|
||||
$model = new Account(['username' => null]);
|
||||
expect($model->validate(['username']))->false();
|
||||
expect($model->getErrors('username'))->equals(['error.username_required']);
|
||||
});
|
||||
|
||||
$this->specify('username should be at least 3 symbols length', function() {
|
||||
$model = new Account(['username' => 'at']);
|
||||
expect($model->validate(['username']))->false();
|
||||
expect($model->getErrors('username'))->equals(['error.username_too_short']);
|
||||
});
|
||||
|
||||
$this->specify('username should be not more than 21 symbols length', function() {
|
||||
$model = new Account(['username' => 'erickskrauch_erickskrauch']);
|
||||
expect($model->validate(['username']))->false();
|
||||
expect($model->getErrors('username'))->equals(['error.username_too_long']);
|
||||
});
|
||||
|
||||
$this->specify('username can contain many cool symbols', function() {
|
||||
$shouldBeValid = [
|
||||
'русский_ник', 'русский_ник_на_грани!', 'numbers1132', '*__*-Stars-*__*', '1-_.!?#$%^&*()[]',
|
||||
'[ESP]Эрик', 'Свят_помидор;', 'зроблена_ў_беларусі:)',
|
||||
];
|
||||
foreach($shouldBeValid as $nickname) {
|
||||
$model = new Account(['username' => $nickname]);
|
||||
expect($nickname . ' passed validation', $model->validate(['username']))->true();
|
||||
expect($model->getErrors('username'))->isEmpty();
|
||||
}
|
||||
});
|
||||
|
||||
$this->specify('username cannot contain some symbols', function() {
|
||||
$shouldBeInvalid = [
|
||||
'nick@name', 'spaced nick',
|
||||
];
|
||||
foreach($shouldBeInvalid as $nickname) {
|
||||
$model = new Account(['username' => $nickname]);
|
||||
expect($nickname . ' fail validation', $model->validate('username'))->false();
|
||||
expect($model->getErrors('username'))->equals(['error.username_invalid']);
|
||||
}
|
||||
});
|
||||
|
||||
$this->specify('username should be unique', function() {
|
||||
$model = new Account(['username' => $this->accounts['admin']['username']]);
|
||||
expect($model->validate('username'))->false();
|
||||
expect($model->getErrors('username'))->equals(['error.username_not_available']);
|
||||
});
|
||||
}
|
||||
|
||||
public function testValidateEmail() {
|
||||
// TODO: пропускать этот тест, если падает ошибка с недостпуностью интернет соединения
|
||||
$this->specify('email required', function() {
|
||||
$model = new Account(['email' => null]);
|
||||
expect($model->validate(['email']))->false();
|
||||
expect($model->getErrors('email'))->equals(['error.email_required']);
|
||||
});
|
||||
|
||||
$this->specify('email should be not more 255 symbols (I hope it\'s impossible to register)', function() {
|
||||
$model = new Account([
|
||||
'email' => 'emailemailemailemailemailemailemailemailemailemailemailemailemailemailemailemailemail' .
|
||||
'emailemailemailemailemailemailemailemailemailemailemailemailemailemailemailemailemail' .
|
||||
'emailemailemailemailemailemailemailemailemailemailemailemailemailemailemailemailemail' .
|
||||
'emailemail', // = 256 symbols
|
||||
]);
|
||||
expect($model->validate(['email']))->false();
|
||||
expect($model->getErrors('email'))->equals(['error.email_too_long']);
|
||||
});
|
||||
|
||||
$this->specify('email should be email (it test can fail, if you don\'t have internet connection)', function() {
|
||||
$model = new Account(['email' => 'invalid_email']);
|
||||
expect($model->validate(['email']))->false();
|
||||
expect($model->getErrors('email'))->equals(['error.email_invalid']);
|
||||
});
|
||||
|
||||
$this->specify('email should be not tempmail', function() {
|
||||
$model = new Account(['email' => 'ibrpycwyjdnt@dropmail.me']);
|
||||
expect($model->validate(['email']))->false();
|
||||
expect($model->getErrors('email'))->equals(['error.email_is_tempmail']);
|
||||
});
|
||||
|
||||
$this->specify('email should be unique', function() {
|
||||
$model = new Account(['email' => $this->accounts['admin']['email']]);
|
||||
expect($model->validate('email'))->false();
|
||||
expect($model->getErrors('email'))->equals(['error.email_not_available']);
|
||||
});
|
||||
}
|
||||
|
||||
public function testSetPassword() {
|
||||
$this->specify('calling method should change password and set latest password hash algorithm', function() {
|
||||
$model = new Account();
|
||||
$model->setPassword('12345678');
|
||||
expect('hash should be set', $model->password_hash)->notEmpty();
|
||||
expect('validation should be passed', $model->validatePassword('12345678'))->true();
|
||||
expect('latest password hash should be used', $model->password_hash_strategy)->equals(Account::PASS_HASH_STRATEGY_YII2);
|
||||
});
|
||||
$model = new Account();
|
||||
$model->setPassword('12345678');
|
||||
$this->assertNotEmpty($model->password_hash, 'hash should be set');
|
||||
$this->assertTrue($model->validatePassword('12345678'), 'validation should be passed');
|
||||
$this->assertEquals(Account::PASS_HASH_STRATEGY_YII2, $model->password_hash_strategy, 'latest password hash should be used');
|
||||
}
|
||||
|
||||
public function testValidatePassword() {
|
||||
@ -164,6 +57,10 @@ class AccountTest extends DbTestCase {
|
||||
}
|
||||
|
||||
public function testHasMojangUsernameCollision() {
|
||||
$this->tester->haveFixtures([
|
||||
'mojangUsernames' => MojangUsernameFixture::class,
|
||||
]);
|
||||
|
||||
$this->specify('Expect true if collision with current username', function() {
|
||||
$model = new Account();
|
||||
$model->username = 'ErickSkrauch';
|
||||
|
@ -1,31 +1,35 @@
|
||||
<?php
|
||||
namespace codeception\common\unit\models;
|
||||
|
||||
use Codeception\Specify;
|
||||
use common\models\confirmations\ForgotPassword;
|
||||
use common\models\confirmations\RegistrationConfirmation;
|
||||
use common\models\confirmations;
|
||||
use common\models\EmailActivation;
|
||||
use tests\codeception\common\fixtures\EmailActivationFixture;
|
||||
use tests\codeception\common\unit\DbTestCase;
|
||||
use tests\codeception\common\unit\TestCase;
|
||||
|
||||
class EmailActivationTest extends DbTestCase {
|
||||
use Specify;
|
||||
class EmailActivationTest extends TestCase {
|
||||
|
||||
public function fixtures() {
|
||||
public function _fixtures() {
|
||||
return [
|
||||
'emailActivations' => EmailActivationFixture::class,
|
||||
];
|
||||
}
|
||||
|
||||
public function testInstantiate() {
|
||||
$this->specify('return valid model type', function() {
|
||||
expect(EmailActivation::findOne([
|
||||
'type' => EmailActivation::TYPE_REGISTRATION_EMAIL_CONFIRMATION,
|
||||
]))->isInstanceOf(RegistrationConfirmation::class);
|
||||
expect(EmailActivation::findOne([
|
||||
'type' => EmailActivation::TYPE_FORGOT_PASSWORD_KEY,
|
||||
]))->isInstanceOf(ForgotPassword::class);
|
||||
});
|
||||
$this->assertInstanceOf(confirmations\RegistrationConfirmation::class, EmailActivation::findOne([
|
||||
'type' => EmailActivation::TYPE_REGISTRATION_EMAIL_CONFIRMATION,
|
||||
]));
|
||||
|
||||
$this->assertInstanceOf(confirmations\ForgotPassword::class, EmailActivation::findOne([
|
||||
'type' => EmailActivation::TYPE_FORGOT_PASSWORD_KEY,
|
||||
]));
|
||||
|
||||
$this->assertInstanceOf(confirmations\CurrentEmailConfirmation::class, EmailActivation::findOne([
|
||||
'type' => EmailActivation::TYPE_CURRENT_EMAIL_CONFIRMATION,
|
||||
]));
|
||||
|
||||
$this->assertInstanceOf(confirmations\NewEmailConfirmation::class, EmailActivation::findOne([
|
||||
'type' => EmailActivation::TYPE_NEW_EMAIL_CONFIRMATION,
|
||||
]));
|
||||
}
|
||||
|
||||
}
|
||||
|
109
tests/codeception/common/unit/validators/EmailValidatorTest.php
Normal file
109
tests/codeception/common/unit/validators/EmailValidatorTest.php
Normal file
@ -0,0 +1,109 @@
|
||||
<?php
|
||||
namespace codeception\common\unit\validators;
|
||||
|
||||
use common\validators\EmailValidator;
|
||||
use tests\codeception\common\fixtures\AccountFixture;
|
||||
use tests\codeception\common\unit\TestCase;
|
||||
use yii\base\Model;
|
||||
|
||||
class EmailValidatorTest extends TestCase {
|
||||
|
||||
/**
|
||||
* @var EmailValidator
|
||||
*/
|
||||
private $validator;
|
||||
|
||||
public function _before() {
|
||||
parent::_before();
|
||||
$this->validator = new EmailValidator();
|
||||
}
|
||||
|
||||
public function testValidateAttributeRequired() {
|
||||
$model = $this->createModel('');
|
||||
$this->validator->validateAttribute($model, 'field');
|
||||
$this->assertEquals(['error.email_required'], $model->getErrors('field'));
|
||||
|
||||
$model = $this->createModel('email');
|
||||
$this->validator->validateAttribute($model, 'field');
|
||||
$this->assertNotEquals(['error.email_required'], $model->getErrors('field'));
|
||||
}
|
||||
|
||||
public function testValidateAttributeLength() {
|
||||
$model = $this->createModel(
|
||||
'emailemailemailemailemailemailemailemailemailemailemailemailemailemailemailemailemail' .
|
||||
'emailemailemailemailemailemailemailemailemailemailemailemailemailemailemailemailemail' .
|
||||
'emailemailemailemailemailemailemailemailemailemailemailemailemailemailemailemailemail' .
|
||||
'@gmail.com' // = 256 symbols
|
||||
);
|
||||
$this->validator->validateAttribute($model, 'field');
|
||||
$this->assertEquals(['error.email_too_long'], $model->getErrors('field'));
|
||||
|
||||
$model = $this->createModel('some-email@gmail.com');
|
||||
$this->validator->validateAttribute($model, 'field');
|
||||
$this->assertNotEquals(['error.email_too_long'], $model->getErrors('field'));
|
||||
}
|
||||
|
||||
public function testValidateAttributeEmail() {
|
||||
$model = $this->createModel('non-email');
|
||||
$this->validator->validateAttribute($model, 'field');
|
||||
$this->assertEquals(['error.email_invalid'], $model->getErrors('field'));
|
||||
|
||||
$model = $this->createModel('non-email@etot-domen-ne-suschestrvyet.de');
|
||||
$this->validator->validateAttribute($model, 'field');
|
||||
$this->assertEquals(['error.email_invalid'], $model->getErrors('field'));
|
||||
|
||||
$model = $this->createModel('valid-email@gmail.com');
|
||||
$this->validator->validateAttribute($model, 'field');
|
||||
$this->assertNotEquals(['error.email_invalid'], $model->getErrors('field'));
|
||||
}
|
||||
|
||||
public function testValidateAttributeTempmail() {
|
||||
$model = $this->createModel('ibrpycwyjdnt@dropmail.me');
|
||||
$this->validator->validateAttribute($model, 'field');
|
||||
$this->assertEquals(['error.email_is_tempmail'], $model->getErrors('field'));
|
||||
|
||||
$model = $this->createModel('valid-email@gmail.com');
|
||||
$this->validator->validateAttribute($model, 'field');
|
||||
$this->assertNotEquals(['error.email_is_tempmail'], $model->getErrors('field'));
|
||||
}
|
||||
|
||||
public function testValidateAttributeUnique() {
|
||||
$this->tester->haveFixtures([
|
||||
'accounts' => AccountFixture::class,
|
||||
]);
|
||||
|
||||
/** @var \common\models\Account $accountFixture */
|
||||
$accountFixture = $this->tester->grabFixture('accounts', 'admin');
|
||||
|
||||
$model = $this->createModel($accountFixture->email);
|
||||
$this->validator->validateAttribute($model, 'field');
|
||||
$this->assertEquals(['error.email_not_available'], $model->getErrors('field'));
|
||||
|
||||
$model = $this->createModel($accountFixture->email);
|
||||
$this->validator->accountCallback = function() use ($accountFixture) {
|
||||
return $accountFixture->id;
|
||||
};
|
||||
$this->validator->validateAttribute($model, 'field');
|
||||
$this->assertNotEquals(['error.email_not_available'], $model->getErrors('field'));
|
||||
$this->validator->accountCallback = null;
|
||||
|
||||
$model = $this->createModel('some-unique-email@gmail.com');
|
||||
$this->validator->validateAttribute($model, 'field');
|
||||
$this->assertNotEquals(['error.email_not_available'], $model->getErrors('field'));
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $fieldValue
|
||||
* @return Model
|
||||
*/
|
||||
private function createModel(string $fieldValue) : Model {
|
||||
$class = new class extends Model {
|
||||
public $field;
|
||||
};
|
||||
|
||||
$class->field = $fieldValue;
|
||||
|
||||
return $class;
|
||||
}
|
||||
|
||||
}
|
@ -11,25 +11,18 @@ class LanguageValidatorTest extends TestCase {
|
||||
use ProtectedCaller;
|
||||
|
||||
public function testGetFilesNames() {
|
||||
$this->specify('get list of 2 languages: ru and en', function() {
|
||||
$model = $this->createModelWithFixturePath();
|
||||
expect($this->callProtected($model, 'getFilesNames'))->equals(['en', 'ru']);
|
||||
});
|
||||
$model = $this->createModelWithFixturePath();
|
||||
$this->assertEquals(['en', 'ru'], $this->callProtected($model, 'getFilesNames'));
|
||||
}
|
||||
|
||||
public function testValidateValue() {
|
||||
$this->specify('get null, because language is supported', function() {
|
||||
$model = $this->createModelWithFixturePath();
|
||||
expect($this->callProtected($model, 'validateValue', 'ru'))->null();
|
||||
});
|
||||
public function testValidateValueSupportedLanguage() {
|
||||
$model = $this->createModelWithFixturePath();
|
||||
$this->assertNull($this->callProtected($model, 'validateValue', 'ru'));
|
||||
}
|
||||
|
||||
$this->specify('get error message, because language is unsupported', function() {
|
||||
$model = $this->createModelWithFixturePath();
|
||||
expect($this->callProtected($model, 'validateValue', 'by'))->equals([
|
||||
$model->message,
|
||||
[],
|
||||
]);
|
||||
});
|
||||
public function testValidateNotSupportedLanguage() {
|
||||
$model = $this->createModelWithFixturePath();
|
||||
$this->assertEquals([$model->message, []], $this->callProtected($model, 'validateValue', 'by'));
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -0,0 +1,106 @@
|
||||
<?php
|
||||
namespace codeception\common\unit\validators;
|
||||
|
||||
use common\validators\UsernameValidator;
|
||||
use tests\codeception\common\fixtures\AccountFixture;
|
||||
use tests\codeception\common\unit\TestCase;
|
||||
use yii\base\Model;
|
||||
|
||||
class UsernameValidatorTest extends TestCase {
|
||||
|
||||
/**
|
||||
* @var UsernameValidator
|
||||
*/
|
||||
private $validator;
|
||||
|
||||
public function _before() {
|
||||
parent::_before();
|
||||
$this->validator = new UsernameValidator();
|
||||
}
|
||||
|
||||
public function testValidateAttributeRequired() {
|
||||
$model = $this->createModel('');
|
||||
$this->validator->validateAttribute($model, 'field');
|
||||
$this->assertEquals(['error.username_required'], $model->getErrors('field'));
|
||||
|
||||
$model = $this->createModel('username');
|
||||
$this->validator->validateAttribute($model, 'field');
|
||||
$this->assertNotEquals(['error.username_required'], $model->getErrors('field'));
|
||||
}
|
||||
|
||||
public function testValidateAttributeLength() {
|
||||
$model = $this->createModel('at');
|
||||
$this->validator->validateAttribute($model, 'field');
|
||||
$this->assertEquals(['error.username_too_short'], $model->getErrors('field'));
|
||||
|
||||
$model = $this->createModel('erickskrauch_erickskrauch');
|
||||
$this->validator->validateAttribute($model, 'field');
|
||||
$this->assertEquals(['error.username_too_long'], $model->getErrors('field'));
|
||||
|
||||
$model = $this->createModel('username');
|
||||
$this->validator->validateAttribute($model, 'field');
|
||||
$this->assertNotEquals(['error.username_too_short'], $model->getErrors('field'));
|
||||
$this->assertNotEquals(['error.username_too_long'], $model->getErrors('field'));
|
||||
}
|
||||
|
||||
public function testValidateAttributePattern() {
|
||||
$shouldBeValid = [
|
||||
'русский_ник', 'русский_ник_на_грани!', 'numbers1132', '*__*-Stars-*__*', '1-_.!$%^&*()[]',
|
||||
'[ESP]Эрик', 'Свят_помидор;', 'зроблена_ў_беларусі:)',
|
||||
];
|
||||
foreach($shouldBeValid as $nickname) {
|
||||
$model = $this->createModel($nickname);
|
||||
$this->validator->validateAttribute($model, 'field');
|
||||
$this->assertNotEquals(['error.username_invalid'], $model->getErrors('field'));
|
||||
}
|
||||
|
||||
$shouldBeInvalid = [
|
||||
'nick@name', 'spaced nick', 'im#hashed', 'quest?ion'
|
||||
];
|
||||
foreach($shouldBeInvalid as $nickname) {
|
||||
$model = $this->createModel($nickname);
|
||||
$this->validator->validateAttribute($model, 'field');
|
||||
$this->assertEquals(['error.username_invalid'], $model->getErrors('field'));
|
||||
}
|
||||
}
|
||||
|
||||
public function testValidateAttributeUnique() {
|
||||
$this->tester->haveFixtures([
|
||||
'accounts' => AccountFixture::class,
|
||||
]);
|
||||
|
||||
/** @var \common\models\Account $accountFixture */
|
||||
$accountFixture = $this->tester->grabFixture('accounts', 'admin');
|
||||
|
||||
$model = $this->createModel($accountFixture->username);
|
||||
$this->validator->validateAttribute($model, 'field');
|
||||
$this->assertEquals(['error.username_not_available'], $model->getErrors('field'));
|
||||
|
||||
$model = $this->createModel($accountFixture->username);
|
||||
$this->validator->accountCallback = function() use ($accountFixture) {
|
||||
return $accountFixture->id;
|
||||
};
|
||||
$this->validator->validateAttribute($model, 'field');
|
||||
$this->assertNotEquals(['error.username_not_available'], $model->getErrors('field'));
|
||||
$this->validator->accountCallback = null;
|
||||
|
||||
$model = $this->createModel('some-unique-username');
|
||||
$this->validator->validateAttribute($model, 'field');
|
||||
$this->assertNotEquals(['error.username_not_available'], $model->getErrors('field'));
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $fieldValue
|
||||
* @return Model
|
||||
*/
|
||||
private function createModel(string $fieldValue) : Model {
|
||||
$class = new class extends Model {
|
||||
public $field;
|
||||
};
|
||||
|
||||
$class->field = $fieldValue;
|
||||
|
||||
return $class;
|
||||
}
|
||||
|
||||
}
|
@ -12,42 +12,66 @@ class UuidValidatorTest extends TestCase {
|
||||
|
||||
public function testValidateAttribute() {
|
||||
$this->specify('expected error if passed empty value', function() {
|
||||
$model = new UuidTestModel();
|
||||
expect($model->validate())->false();
|
||||
expect($model->getErrors('attribute'))->equals(['Attribute must be valid uuid']);
|
||||
$validator = new UuidValidator();
|
||||
$model = $this->createModel();
|
||||
$validator->validateAttribute($model, 'attribute');
|
||||
$this->assertTrue($model->hasErrors());
|
||||
$this->assertEquals(['Attribute must be valid uuid'], $model->getErrors('attribute'));
|
||||
});
|
||||
|
||||
$this->specify('expected error if passed invalid string', function() {
|
||||
$model = new UuidTestModel();
|
||||
$validator = new UuidValidator();
|
||||
$model = $this->createModel();
|
||||
$model->attribute = '123456789';
|
||||
expect($model->validate())->false();
|
||||
expect($model->getErrors('attribute'))->equals(['Attribute must be valid uuid']);
|
||||
$validator->validateAttribute($model, 'attribute');
|
||||
$this->assertTrue($model->hasErrors());
|
||||
$this->assertEquals(['Attribute must be valid uuid'], $model->getErrors('attribute'));
|
||||
});
|
||||
|
||||
$this->specify('no errors if passed nil uuid and allowNil is set to true', function() {
|
||||
$validator = new UuidValidator();
|
||||
$model = $this->createModel();
|
||||
$model->attribute = '00000000-0000-0000-0000-000000000000';
|
||||
$validator->validateAttribute($model, 'attribute');
|
||||
$this->assertFalse($model->hasErrors());
|
||||
});
|
||||
|
||||
$this->specify('no errors if passed nil uuid and allowNil is set to false', function() {
|
||||
$validator = new UuidValidator();
|
||||
$validator->allowNil = false;
|
||||
$model = $this->createModel();
|
||||
$model->attribute = '00000000-0000-0000-0000-000000000000';
|
||||
$validator->validateAttribute($model, 'attribute');
|
||||
$this->assertTrue($model->hasErrors());
|
||||
$this->assertEquals(['Attribute must be valid uuid'], $model->getErrors('attribute'));
|
||||
});
|
||||
|
||||
$this->specify('no errors if passed valid uuid', function() {
|
||||
$model = new UuidTestModel();
|
||||
$validator = new UuidValidator();
|
||||
$model = $this->createModel();
|
||||
$model->attribute = Uuid::uuid();
|
||||
expect($model->validate())->true();
|
||||
$validator->validateAttribute($model, 'attribute');
|
||||
$this->assertFalse($model->hasErrors());
|
||||
});
|
||||
|
||||
$this->specify('no errors if passed uuid string without dashes and converted to standart value', function() {
|
||||
$model = new UuidTestModel();
|
||||
$validator = new UuidValidator();
|
||||
$model = $this->createModel();
|
||||
$originalUuid = Uuid::uuid();
|
||||
$model->attribute = str_replace('-', '', $originalUuid);
|
||||
expect($model->validate())->true();
|
||||
expect($model->attribute)->equals($originalUuid);
|
||||
$validator->validateAttribute($model, 'attribute');
|
||||
$this->assertFalse($model->hasErrors());
|
||||
$this->assertEquals($originalUuid, $model->attribute);
|
||||
});
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
class UuidTestModel extends Model {
|
||||
public $attribute;
|
||||
|
||||
public function rules() {
|
||||
return [
|
||||
['attribute', UuidValidator::class],
|
||||
];
|
||||
/**
|
||||
* @return Model
|
||||
*/
|
||||
public function createModel() {
|
||||
return new class extends Model {
|
||||
public $attribute;
|
||||
};
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -1,6 +1,8 @@
|
||||
# Codeception Test Suite Configuration
|
||||
|
||||
# suite for unit (internal) tests.
|
||||
# RUN `build` COMMAND AFTER ADDING/REMOVING MODULES.
|
||||
|
||||
class_name: UnitTester
|
||||
modules:
|
||||
enabled:
|
||||
- Yii2:
|
||||
part: [orm, email, fixtures]
|
||||
config:
|
||||
Yii2:
|
||||
configFile: '../config/console/unit.php'
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user